Compare commits

...

64 Commits

Author SHA1 Message Date
Lara REALI
c578ee926c Merge branch 'phoenix' into reborn 2023-06-26 11:13:08 +02:00
Lara REALI
fb6d96fb29 rm index.js change icon and title , delete report webvital 2023-06-26 10:50:47 +02:00
Alexandre POMMIER
0ceea91dc0 merge apommier dipper 2023-06-26 10:49:01 +02:00
Alexandre POMMIER
369ab63f8a clen a bit and add verifypassword who now add to channel if good pass 2023-06-26 10:47:15 +02:00
Elisee ADJIGUIDI
badd6a8379 merge 2023-06-26 10:45:08 +02:00
Elisee ADJIGUIDI
612d0084c0 password 2023-06-26 10:38:22 +02:00
Alexandre POMMIER
baa9b90e5d merge done 2023-06-26 08:00:30 +02:00
Alexandre POMMIER
a6dfe6940f big big merge 2023-06-26 07:55:12 +02:00
Alexandre POMMIER
0d80c118b4 Merge remote-tracking branch 'origin/phoenix' into reborn 2023-06-26 07:46:36 +02:00
Alexandre POMMIER
984b374500 fix alert in modal setting 2023-06-26 07:46:00 +02:00
Lara REALI
53106b33bc fix log color 2023-06-26 07:26:27 +02:00
Alexandre POMMIER
b59e987c7d clean chat api and pong from commentary 2023-06-26 07:06:16 +02:00
Lara REALI
49d73b92d3 log color to fix 2023-06-26 06:58:09 +02:00
Elisee ADJIGUIDI
cd4e414d16 resize name conv 2023-06-26 06:36:29 +02:00
Alexandre POMMIER
42cdd645c8 Merge remote-tracking branch 'origin/dipper' into reborn 2023-06-26 06:05:44 +02:00
Alexandre POMMIER
02ab84add4 mute work 2023-06-26 06:05:14 +02:00
Elisee ADJIGUIDI
94e6250e17 limit conv name 2023-06-26 06:00:38 +02:00
Elisee ADJIGUIDI
9f323ee15d from username to nickname 2023-06-26 05:49:26 +02:00
Elisee ADJIGUIDI
3d74296bb8 recentre alerte 2023-06-26 05:09:47 +02:00
Elisee ADJIGUIDI
ba5490cf90 Alert mute 2023-06-26 04:44:08 +02:00
Alexandre POMMIER
8ebeabb386 Merge remote-tracking branch 'origin/phoenix' into reborn 2023-06-26 04:18:16 +02:00
Lara REALI
84cc25a5a1 reload fix , friends , navbarSocial change margin friends 2023-06-26 04:17:07 +02:00
Alexandre POMMIER
abf09f24fd merge reborn 2023-06-26 04:16:48 +02:00
Alexandre POMMIER
cd6de16511 fix chan invite 2023-06-26 04:06:09 +02:00
Elisee ADJIGUIDI
13dfa6cd95 retrait compteur dans alert et recentre profile 2023-06-26 04:04:51 +02:00
Elisee ADJIGUIDI
9026a81680 merge 2023-06-26 03:02:04 +02:00
Lara REALI
26b3c82790 merge error 2023-06-26 02:54:48 +02:00
Elisee ADJIGUIDI
ba60337c71 unbanned unblocked 2023-06-26 02:40:29 +02:00
Lara REALI
87d342d89a merge apommier 2023-06-26 02:39:09 +02:00
Alexandre POMMIER
152d0541d4 add useeffect app for return 2023-06-26 02:27:43 +02:00
Lara REALI
322aecc182 quit + alert +addsesion 2023-06-26 02:22:47 +02:00
Elisee ADJIGUIDI
80ff5f6c9f new alert bad input qrcode resize button chat modif alert name already taken 2023-06-26 01:47:41 +02:00
Alexandre POMMIER
4151350162 fix login with other app, pong greater speed at start, fix in game status ?, rename home.js to loginbutton.tsx 2023-06-26 01:31:46 +02:00
Lara REALI
b61531d8d2 color for qr input + text in chat input + w = wall 2023-06-26 00:32:42 +02:00
Lara REALI
1e9946859c augment desactivate 2fa size + blur OK + Friend list css OK Invite button suppress comment spectate button 2023-06-25 21:51:21 +02:00
Lara REALI
007dbe1832 Merge branch 'ereali' into reborn 2023-06-25 00:39:05 +02:00
Alexandre POMMIER
9098c29287 fix invite double channel when add friend fix invite, history power up time limited wall 2023-06-25 00:30:30 +02:00
Lara REALI
cf0edf5bc0 Merge remote-tracking branch 'origin/apommier' into ereali 2023-06-24 20:18:46 +02:00
Alexandre POMMIER
2f777480a0 try locahost 2023-06-24 20:12:13 +02:00
Lara REALI
92f3f496de Friend request css + change navbar Social+ button border qr butonn desactivate qr 2023-06-24 20:02:14 +02:00
Alexandre POMMIER
c6fe3a5a99 fix invite and match history not done 2023-06-24 19:39:16 +02:00
Alexandre POMMIER
38052b5034 fix invit 2023-06-24 18:19:41 +02:00
Alexandre POMMIER
fc280662b9 merge 2023-06-24 16:17:16 +02:00
Lara REALI
b04683576d merge apommier 2023-06-24 15:52:24 +02:00
Lara REALI
c011ea2b04 merge 2023-06-24 15:50:10 +02:00
Alexandre POMMIER
e44320a88f Merge remote-tracking branch 'origin/ereali' into apommier 2023-06-24 15:39:27 +02:00
Alexandre POMMIER
cf7c648813 before merge 2023-06-24 15:38:16 +02:00
Elisee ADJIGUIDI
a84b932355 merge 2023-06-24 15:14:08 +02:00
Elisee ADJIGUIDI
44fb3cdecd responsive pages/game nickname already Taken/Nickname too short 2023-06-24 14:35:50 +02:00
Lara REALI
6fd9660bff message sans decalage 2023-06-24 01:04:47 +02:00
Lara REALI
bdeb414c09 border message + responsive on profile 2023-06-24 00:51:36 +02:00
Alexandre POMMIER
071f30764a canvas background page, fix message mute, win loss in profile 2023-06-24 00:51:32 +02:00
Elisee ADJIGUIDI
de59d21671 change 2023-06-24 00:37:20 +02:00
Elisee ADJIGUIDI
6ad04baf06 merge 2023-06-23 20:32:35 +02:00
Alexandre POMMIER
d5e3532bd0 merge all all 2023-06-23 20:30:14 +02:00
Alexandre POMMIER
6d1cd933e2 Merge remote-tracking branch 'origin/ereali' into apommier 2023-06-23 20:21:36 +02:00
Alexandre POMMIER
b50d789d1d merge all syd 2023-06-23 20:20:10 +02:00
Alexandre POMMIER
c07a169794 fix mute ? fix socket fix infinite request profile, modify port 2023-06-23 19:59:23 +02:00
Elisee ADJIGUIDI
72a4f42cdb change design 2023-06-23 19:59:07 +02:00
Lara REALI
4d98765009 margin on leaderboard pic + auto input qr 2023-06-23 19:58:45 +02:00
Lara REALI
b27cb189b3 Qrcode number without arrows 2023-06-23 18:45:59 +02:00
Elisee ADJIGUIDI
0d42eda749 change 2023-06-23 15:38:58 +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
74 changed files with 1454 additions and 2441 deletions

3
.env
View File

@ -14,6 +14,7 @@
NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf" NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf"
# BASE_URL=http://localhost # BASE_URL=http://localhost
# SOCKET_URL=localhost:8080
BASE_URL=localhost:8080 BASE_URL=localhost:8080
REACT_APP_BASE_URL=localhost:8080 REACT_APP_BASE_URL=localhost:8080
REDIRECT_URI=http://localhost:8080/api/auth/login REDIRECT_URI=http://localhost:8080/api/auth/login
@ -43,4 +44,4 @@ REACT_HOST=0.0.0.0
JWT_SECRET=secrethere JWT_SECRET=secrethere
# REDIRECT_URI=http://localhost:80/api/auth/login # REDIRECT_URI=http://localhost:80/api/auth/login
API_SECRET=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 API_SECRET=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
CLIENT_UID=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41 CLIENT_UID=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
#.env .env
containers/react/.env
backend/node_modules/ backend/node_modules/
containers/backend/dist/ containers/backend/dist/

View File

@ -1 +1 @@
ALTER USER postgres WITH PASSWORD 'pass'; ALTER USER postgres WITH PASSWORD 'postgres';

View File

@ -10,7 +10,7 @@ server {
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:8081;
} }
location /api { location /api {
@ -21,7 +21,7 @@ server {
proxy_pass http://api:3000/api; proxy_pass http://api:3000/api;
} }
location /socket { location /socket.io {
# Forward requests to socket server running on port 4001 # Forward requests to socket server running on port 4001
if ($request_uri ~ ^/socket/4001) { if ($request_uri ~ ^/socket/4001) {
proxy_pass http://chat:4001; proxy_pass http://chat:4001;

View File

@ -1,22 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});

View File

@ -6,274 +6,238 @@
/* 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/26 10:16:19 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
import { Controller, Request, Req, Get, Post, UseGuards, Redirect, Res, Body, UploadedFile, UseInterceptors} from '@nestjs/common'; import { Controller, Request, Req, Get, Post, UseGuards, Redirect, Res, Body, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express'; import { FileInterceptor } from '@nestjs/platform-express';
import { JwtAuthGuard } from './auth/jwt-auth.guard'; import { JwtAuthGuard } from './auth/jwt-auth.guard';
import { AuthService } from './auth/auth.service'; import { AuthService } from './auth/auth.service';
import { loginClass } from './auth/login42' import { loginClass } from './auth/login42'
import { ChatService } from './chat/chat.service'; import { ChatService } from './chat/chat.service';
import { UsersService } from './users/users.service'; import { UsersService } from './users/users.service';
import { MatchLog } from './model/user.entity' import { MatchLog } from './model/user.entity'
import { generate } from 'rxjs';
// import { generateQRcode } from './users/2fa';
import { generateOTP } from './users/2fa'; 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 { formatWithOptions } from 'util';
//2fa
// import { initStorage, getUser, setUser } from './storage';
// import { AuthGuard } from '@nestjs/passport';
// import { Login42 } from './auth/login42'
// import { loginClass } from './auth/test'
@Controller('/api') @Controller('/api')
export class AppController { export class AppController {
constructor(private authService: AuthService, constructor(private authService: AuthService,
private loginClass: loginClass, private loginClass: loginClass,
private chatService: ChatService, private chatService: ChatService,
private userService: UsersService, ) {} private userService: UsersService,) { }
kFactor = 36; kFactor = 36;
scaleFactor = 400; scaleFactor = 400;
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// User // User
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Get('/profile') @Get('/profile')
async getProfile(@Request() req) { async getProfile(@Request() req) {
// const myJSON = JSON.stringify(req.user); return await this.userService.findOne(req.user.username);
// console.log(`req user api= ${req.user}`) }
// console.log(`json user api= ${myJSON}`)
// return req.user;
return await this.userService.findOne(req.user.username);
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/user') @Post('/logout')
async getUser( @Body() data: any) { async logout(@Request() req, @Body() data: any) {
console.log(`usernamewwww= ${data.username}`) const user = await this.userService.findOne(req.user.username)
return await this.userService.findOne(data.username); // return await this.userService.refuseInvite(user, data.username);
} if(!user)
return ;
if (user.sessionNumber === 1)
{
user.status = 0;
}
user.sessionNumber--;
this.userService.save(user);
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Get('/users') @Post('/user')
async getUsers( @Body() data: any) { async getUser(@Body() data: any) {
console.log(`usernamewwww= ${data.username}`) return await this.userService.findOne(data.username);
return await this.userService.findAll(); }
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Get('/friends') @Get('/users')
async getFriends(@Request() req) { async getUsers(@Body() data: any) {
// return await this.userService.getFriends(req.user.username); return await this.userService.findAll();
return await this.userService.getFriends(req.user.username); }
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/friend')//need to do it 2 time when user accept one for each @Get('/friends')
async newFriend(@Request() req, @Body() data: any) { async getFriends(@Request() req) {
// return await this.userService.getFriends(req.user.username); return await this.userService.getFriends(req.user.username);
console.log(`user= ${req.user.username}`) }
const user = await this.userService.findOne(req.user.username)
if (!user)
return (0);
//create personnal conv for user
//await this.userService.addFriend(user, data.username);
@UseGuards(JwtAuthGuard)
@Post('/friend')
async newFriend(@Request() req, @Body() data: any) {
const user = await this.userService.findOne(req.user.username)
if (!user)
return (0);
if (user.friends.find(item => item === data.username)) {
user.friendRequest = user.friendRequest.filter((item) => item !== data.username);
this.userService.save(user);
return (1);
}
const conv = {
id: null,
name: req.user.username + ", " + data.username,
banned: [],
admin: [],
muted: [],
members: [],
owner: req.user.username,
password: null,
messages: null,
group: false,
private: false,
};
conv.members.push(req.user.username);
conv.members.push(data.username);
await this.chatService.createConv(conv);
return await this.userService.addFriend(user, data.username);
// const amIhere = data.members.includes(req.user.username); }
// if (!amIhere)
const conv = {
id: null,
name: req.user.username + ", " + data.username,
banned: [],
admin: [],
muted: [],
members: [],
owner: req.user.username,
password: null,
messages: null,
group: false,
private: false,
}; @UseGuards(JwtAuthGuard)
conv.members.push(req.user.username); @Post('/block')
conv.members.push(data.username); async newBlocked(@Request() req, @Body() data: any) {
await this.chatService.createConv(conv); if (data.username === req.user.username)
return (0);
const user = await this.userService.findOne(req.user.username)
return await this.userService.addBlocked(user, data.username);
}
return await this.userService.addFriend(user, data.username); @UseGuards(JwtAuthGuard)
} @Post('/invite')
async newInvite(@Request() req, @Body() data: any) {
if (data.username === req.user.username)
return (0);
const user = await this.userService.findOne(data.username)
if (!user)
return (0);
return await this.userService.newInvite(user, req.user.username);
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/block') @Get('/inviteRequest')
async newBlocked(@Request() req, @Body() data: any) { async getInvite(@Request() req) {
// return await this.userService.getFriends(req.user.username); return await this.userService.getInvite(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)
return await this.userService.addBlocked(user, data.username);
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/invite') @Post('/refuseInvite')
async newInvite(@Request() req, @Body() data: any) { async refuseInvite(@Request() req, @Body() data: any) {
console.log(`user= ${req.user.username}`) const user = await this.userService.findOne(req.user.username)
if (data.username === req.user.username) return await this.userService.refuseInvite(user, data.username);
return (0); }
const user = await this.userService.findOne(data.username)
if (!user)
return (0);
return await this.userService.newInvite(user, req.user.username);
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Get('/inviteRequest') @Post('/status')
async getInvite(@Request() req) { async setStatus(@Request() req, @Body() data: any) {
// return await this.userService.getFriends(req.user.username); const user = await this.userService.findOne(req.user.username);
console.log(`useawdawd\n\n\nr= ${req.user.username}`)
// const user = await this.userService.findOne(req.user.username)
return await this.userService.getInvite(req.user.username);
}
@UseGuards(JwtAuthGuard) user.status = data.status;
@Post('/refuseInvite') await this.userService.save(user);
async refuseInvite(@Request() req, @Body() data: any) { }
// return await this.userService.getFriends(req.user.username);
// console.log(`useawdawd\n\n\nr= ${req.user.username}`)
const user = await this.userService.findOne(req.user.username)
return await this.userService.refuseInvite(user, data.username);
}
@UseGuards(JwtAuthGuard)
@Post('/status')
async setStatus(@Request() req, @Body() data: any) {
const user = await this.userService.findOne(req.user.username);
user.status = data.status;
await this.userService.save(user);
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/nickname') @Post('/nickname')
async setNickname(@Request() req, @Body() data: any) { async setNickname(@Request() req, @Body() data: any) {
// let user = req.user const taken = await this.userService.findNickname(data.nickname)
// user.nickname = data.nickname if (taken)
console.log(`user= ${req.user.username}`) return (0);
let user = await this.userService.findOne(req.user.username) let user = await this.userService.findOne(req.user.username)
user.nickname = data.nickname; user.nickname = data.nickname;
// return await this.userService.getFriends(req.user.username);
return await this.userService.save(user); return await this.userService.save(user);
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/picture') @Post('/picture')
@UseInterceptors(FileInterceptor('photo')) @UseInterceptors(FileInterceptor('photo'))
async setProfilPicture(@Request() req, @UploadedFile() file: Express.Multer.File) { async setProfilPicture(@Request() req, @UploadedFile() file: Express.Multer.File) {
let user = await this.userService.findOne(req.user.username) let user = await this.userService.findOne(req.user.username)
if (!file) if (!file)
user.photo = null; user.photo = null;
else else
user.photo = file.buffer; user.photo = file.buffer;
return await this.userService.save(user); return await this.userService.save(user);
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/getPicture') @Post('/getPicture')
async getProfilPicture(@Body() data: any) { async getProfilPicture(@Body() data: any) {
// console.log(`dataaaaa= ${data.username}`)
return await this.userService.getPic(data.username) return await this.userService.getPic(data.username)
// return user.photo
// const photoData = user.photo;
// Buffer.from(user.photo, 'binary').buffer;
// const arrayBuffer = ArrayBuffer.from(photoData, 'binary');
// return await this.userService.save(user);
} }
//======================================================================================================== @UseGuards(JwtAuthGuard)
//======================================================================================================== @Post('/addSession')
// Pong async addSession(@Request() req) {
//======================================================================================================== const user = await this.userService.findOne(req.user.username);
//======================================================================================================== user.sessionNumber += 1;
if (user.status !== 2)
user.status = 1;
await this.userService.save(user);
}
//========================================================================================================
//========================================================================================================
// Pong
//========================================================================================================
//========================================================================================================
@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);
user.rank = newRank; user.rank = newRank;
console.log(`win new rank= ${newRank}`);
console.log(`data win = ${data}`)
const newMatch = new MatchLog; const newMatch = new MatchLog;
newMatch.myScore = data.myScore; newMatch.myScore = data.myScore;
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++;
user.status = 1;
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 * (0 - Esp); const newRank = user.rank + this.kFactor * (0 - Esp);
user.rank = newRank; user.rank = newRank;
console.log(`loss new rank= ${newRank}`);
console.log(`data loss = ${data}`)
const newMatch = new MatchLog; const newMatch = new MatchLog;
newMatch.myScore = data.myScore; newMatch.myScore = data.myScore;
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);
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Get('/rank') @Get('/rank')
async getRank(@Request() req) async getRank(@Request() req) {
{ const user = await this.userService.findOne(req.user.username);
const user = await this.userService.findOne(req.user.username); return user.rank;
return user.rank; }
}
// @UseGuards(JwtAuthGuard)
@Get('/ranking') @Get('/ranking')
async getRanking() async getRanking()
{ {
@ -284,42 +248,27 @@ export class AppController {
@Post('/partyInvite') @Post('/partyInvite')
async partyInvite(@Request() req, @Body() data: any) 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); const user = await this.userService.findOne(data.username);
user.partyInvite = user.partyInvite || []; user.partyInvite = user.partyInvite || [];
user.partyInvite.push({ username: req.user.username, gameId: data.gameId }); user.partyInvite.push({ username: req.user.username, gameId: data.gameId });
console.log("usr === ", user)
await this.userService.save(user); await this.userService.save(user);
// user.partyInvite.push(data);
console.log("invite === ", user.partyInvite)
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Get('/partyInvite') @Get('/partyInvite')
async getPartyInvite(@Request() req, @Body() data: any) async getPartyInvite(@Request() req)
{ {
//find data.username and add invite to list
const user = await this.userService.findOne(req.user.username); const user = await this.userService.findOne(req.user.username);
user.partyInvite = user.partyInvite || []; user.partyInvite = user.partyInvite || [];
// this.userService.save(user);
// user.partyInvite.push(data);
// console.log("data invite === ", data.username)
return user.partyInvite; return user.partyInvite;
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/deleteInvite') @Post('/deleteInvite')
async deleteInvite(@Request() req, @Body() data: any) async deleteInvite(@Request() req, @Body() data: any)
{ {
console.log("delete invite user= ", data.username)
const user = await this.userService.findOne(req.user.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); user.partyInvite = user.partyInvite.filter((item) => Object.values(item)[1] !== data.username);
console.log("user.partyInvite after", user.partyInvite)
this.userService.save(user); this.userService.save(user);
} }
@ -327,54 +276,37 @@ export class AppController {
@Post('/history') @Post('/history')
async getHistory(@Body() data: any) async getHistory(@Body() data: any)
{ {
// const user = await this.userService.findOne(req.user.username);
// return user.rank;
return await this.userService.getHistory(data.username); return await this.userService.getHistory(data.username);
// if (user) {
// const children = user.children;
// console.log(user);
// console.log(user.children); // or perform any operations with the children
// return children;
// // You can also access specific properties of each child
// // children.forEach((child) => {
// // console.log(child.id);
// // console.log(child.opponent);
// // // Access other child properties as needed
// // });
// }
} }
@UseGuards(JwtAuthGuard)
@Post('/quit')
async setOffline(@Request() req) {
const user = await this.userService.findOne(req.user.username);
if (!user)
return ;
user.sessionNumber--;
console.log("seesion number=", user.sessionNumber)
if (!user.sessionNumber)
user.status = 0;
await this.userService.save(user);
}
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// Auth // Auth
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// import { Prisma } from "@prisma/client";
// import { Request, Response, NextFunction } from "express";
// import { prisma } from "../server";
@Redirect('http://' + process.env.BASE_URL + '/token', 302) @Redirect('http://' + process.env.BASE_URL + '/token', 302)
@Get('auth/login') @Get('auth/login')
async login2(@Req() request: Request) { async login2(@Req() request: Request) {
const url = request.url; const url = request.url;
const user = await this.loginClass.Login42(url); const user = await this.loginClass.Login42(url);
console.log(`user in auth/login= ${user}`);
console.log(`user in auth/login= ${user.username}`);
const data = await this.authService.login(user); const data = await this.authService.login(user);
console.log(`all data in api = ${data}`)
const myJSON = JSON.stringify(data); const myJSON = JSON.stringify(data);
console.log(`all data json version= ${myJSON}`) const token = (await data).access_token;
console.log(`data in api = ${(await data).access_token}`)
// console.log(`data i = ${(await data).access_token}`)
const token = (await data).access_token;
// console
await this.userService.save(user); await this.userService.save(user);
return { url: 'http://' + process.env.BASE_URL + `/token?data=${encodeURIComponent(JSON.stringify(token))}` }; return { url: 'http://' + process.env.BASE_URL + `/token?data=${encodeURIComponent(JSON.stringify(token))}` };
} }
@ -387,16 +319,13 @@ export class AppController {
return user.otp_enabled; return user.otp_enabled;
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/otp') @Post('/otp')
async createOTP(@Request() req) async createOTP(@Request() req)
{ {
const user = await this.userService.findOne(req.user.username); const user = await this.userService.findOne(req.user.username);
// const user2 = await this.userService.findOne(req.user.username);
const res = await generateOTP(user); const res = await generateOTP(user);
await this.userService.save(user); await this.userService.save(user);
// console.log(user);
return res; return res;
} }
@ -406,8 +335,6 @@ export class AppController {
{ {
const user = await this.userService.findOne(req.user.username); const user = await this.userService.findOne(req.user.username);
const res = await VerifyOTP(user, data.token) const res = await VerifyOTP(user, data.token)
console.log('token in verify=', data.token)
console.log('res in verify=', res)
await this.userService.save(user); await this.userService.save(user);
return res return res
} }
@ -418,7 +345,6 @@ export class AppController {
{ {
const user = await this.userService.findOne(req.user.username); const user = await this.userService.findOne(req.user.username);
const res = await ValidateOTP(user, data.token) const res = await ValidateOTP(user, data.token)
// await this.userService.save(user);
return res return res
} }
@ -429,192 +355,153 @@ export class AppController {
const user = await this.userService.findOne(req.user.username); const user = await this.userService.findOne(req.user.username);
user.otp_verified = false; user.otp_verified = false;
await this.userService.save(user); await this.userService.save(user);
// const res = await ValidateOTP(user, data.token)
// await this.userService.save(user);
// return res
} }
// @UseGuards(JwtAuthGuard)
// @Get('/QRcode')
// async createQrCode(@Request() req)
// {
// return (await generateQRcode(req));
// }
@UseGuards(JwtAuthGuard)
@Post('/quit')
async setOffline(@Request() req) {
const user = await this.userService.findOne(req.user.username);
user.status = 0;
await this.userService.save(user);
console.log("User quit");
}
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// Chat // Chat
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/conv') @Post('/conv')
async createConv(@Request() req, @Body() data: any) { async createConv(@Request() req, @Body() data: any) {
///create conv and return it ? id? const amIhere = data.members.includes(req.user.username);
console.log(`data post /conv= ${data}`); if (!amIhere)
console.log(`data post /conv= ${data.members}`); data.members.push(req.user.username)
// console.log(`data post /conv= ${data.name}`); data.admin = []
data.admin.push(req.user.username)
// const param = data; data.owner = req.user.username
const amIhere = data.members.includes(req.user.username); data.group = true;
if (!amIhere) return await this.chatService.createConv(data);
data.members.push(req.user.username)
// let test = {id: 2, members: "cc"};
data.admin = []
data.admin.push(req.user.username)
data.owner = req.user.username
data.group = true;
return await this.chatService.createConv(data);
// res.json(messages);
}
@UseGuards(JwtAuthGuard)
@Get('/conv')
async getConv(@Request() req) {
return await this.chatService.getConv(req.user.username);
}
@UseGuards(JwtAuthGuard)
@Get('/convs')
async getConvs() {
return await this.chatService.findAll();
}
@UseGuards(JwtAuthGuard)
@Post('/convId')
async getConvById(@Body() data: any) {
return await this.chatService.findConv(data.convId);
}
@UseGuards(JwtAuthGuard)
@Post('/message')
async postMessage(@Request() req, @Body() data: any) {
//if i can post post ?
let message =
{
convid: data.convId,
sender: data.sender,
text: data.text,
// createdAt: null,
id: null,
}
console.log(data);
return await this.chatService.createMessage(message, req.user.username);
}
@UseGuards(JwtAuthGuard)
@Post('/member')
async getMember(@Body() data: any) {
console.log(data);
console.log(`get member= ${data.convId}`);
return await this.chatService.findConv(data.convId);
}
@UseGuards(JwtAuthGuard)
@Post('/getMessage')
async getMessage(@Body() data: any) {
console.log(data);
// console.log(req.query)
console.log(`data get /conv= ${data.convId}`);
// let test = {id: 2, members: "cc"};
return await this.chatService.getMessages(data.convId);
// return await this.chatService.getConv(req.user.username);
// res.json(messages);
}
@UseGuards(JwtAuthGuard)
@Post('/name')
async setName(@Body() data: any) {
//find conv
// data.convId
return await this.chatService.setName(data.convId, data.name)
}
@UseGuards(JwtAuthGuard)
@Post('/password')
async setPassword(@Body() data: any) {
return await this.chatService.setPassword(data.convId, data.password)
}
@UseGuards(JwtAuthGuard)
@Post('/verifyPassword')
async verifyPassword(@Body() data: any) {
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) @UseGuards(JwtAuthGuard)
@Post('/ban') @Get('/conv')
async banUser(@Body() data: any) { async getConv(@Request() req) {
if (!data.username) return await this.chatService.getConv(req.user.username);
return ;
return await this.chatService.banUser(data.convId, data.username)
} }
@UseGuards(JwtAuthGuard)
@Post('/admin')
async setAdmin(@Body() data: any) {
if (!data.username)
return ;
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)
@Post('/isAdmin')
async isAdmin(@Request() req, @Body() data: any) {
console.log("isdamin= ", req.user.username, " id=", data.convId)
return await this.chatService.isAdmin(data.convId, req.user.username)
}
@UseGuards(JwtAuthGuard)
@Post('/private')
async setPrivate(@Body() data: any) {
return await this.chatService.setPrivate(data.convId)
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/allowed') @Get('/convs')
async isAllowed(@Request() req, @Body() data: any) { async getConvs() {
return await this.chatService.isAllowed(data.convId, req.user.username) return await this.chatService.findAll();
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/join') @Post('/convId')
async joinChannel(@Request() req, @Body() data: any) { async getConvById(@Body() data: any) {
return await this.chatService.joinChannel(data.convId, req.user.username) return await this.chatService.findConv(data.convId);
} }
}
@UseGuards(JwtAuthGuard)
@Post('/message')
async postMessage(@Request() req, @Body() data: any) {
let message =
{
convid: data.convId,
sender: data.sender,
text: data.text,
id: null,
}
console.log(data);
return await this.chatService.createMessage(message, req.user.username);
}
@UseGuards(JwtAuthGuard)
@Post('/member')
async getMember(@Body() data: any) {
console.log(data);
console.log(`get member= ${data.convId}`);
return await this.chatService.findConv(data.convId);
}
@UseGuards(JwtAuthGuard)
@Post('/getMessage')
async getMessage(@Body() data: any) {
return await this.chatService.getMessages(data.convId);
}
@UseGuards(JwtAuthGuard)
@Post('/name')
async setName(@Body() data: any) {
return await this.chatService.setName(data.convId, data.name)
}
@UseGuards(JwtAuthGuard)
@Post('/password')
async setPassword(@Body() data: any) {
// console.log("PASSSSSSSSSSSSSSSSSSSSSSSSSSs= ", data.password);
return await this.chatService.setPassword(data.convId, data.password)
}
@UseGuards(JwtAuthGuard)
@Post('/verifyPassword')
async verifyPassword(@Request() req, @Body() data: any) {
// const user = await this.userService.findOne(req.user.username);
return await this.chatService.verifyPassword(data.convId, data.password, req.user.username)
}
@UseGuards(JwtAuthGuard)
@Post('/inviteConv')
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)
@Post('/admin')
async setAdmin(@Body() data: any) {
if (!data.username)
return;
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, data.time)
}
@UseGuards(JwtAuthGuard)
@Post('/isAdmin')
async isAdmin(@Request() req, @Body() data: any) {
console.log("isdamin= ", req.user.username, " id=", data.convId)
return await this.chatService.isAdmin(data.convId, req.user.username)
}
@UseGuards(JwtAuthGuard)
@Post('/private')
async setPrivate(@Body() data: any) {
return await this.chatService.setPrivate(data.convId, true)
}
@UseGuards(JwtAuthGuard)
@Post('/public')
async setPublic(@Body() data: any) {
return await this.chatService.setPrivate(data.convId, false)
}
@UseGuards(JwtAuthGuard)
@Post('/allowed')
async isAllowed(@Request() req, @Body() data: any) {
return await this.chatService.isAllowed(data.convId, req.user.username)
}
@UseGuards(JwtAuthGuard)
@Post('/join')
async joinChannel(@Request() req, @Body() data: any) {
return await this.chatService.joinChannel(data.convId, req.user.username)
}
}

View File

@ -2,16 +2,8 @@ import { Module } from '@nestjs/common';
import { AppController } from './app.controller'; import { AppController } from './app.controller';
import { AppService } from './app.service'; import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module'; import { AuthModule } from './auth/auth.module';
import { loginClass } from './auth/login42'; import { loginClass } from './auth/login42';
// import { UsersService } from './users/users.service'; // in add
// import { TypeOrmModule } from '@nestjs/typeorm';
// import { getTypeOrmConfig } from './config/config.service';
// import { User } from './model/item.entity';
// import { UsersService } from './users/users.service';
import { UsersModule } from './users/users.module'; import { UsersModule } from './users/users.module';
// import { ChatService } from './chat/chat.service';
import { ChatModule } from './chat/chat.module'; import { ChatModule } from './chat/chat.module';
@Module({ @Module({
@ -23,7 +15,5 @@ import { ChatModule } from './chat/chat.module';
], ],
controllers: [AppController], controllers: [AppController],
providers: [AppService, loginClass,], providers: [AppService, loginClass,],
// providers: [AppService, UsersService],//in add
}) })
export class AppModule {} export class AppModule {}

View File

@ -1,23 +1,8 @@
// import { Module } from '@nestjs/common';
// import { AuthService } from './auth.service';
// import { UsersModule } from '../users/users.module';
// import { PassportModule } from '@nestjs/passport';
// import { LocalStrategy } from './local.strategy';
// @Module({
// imports: [UsersModule, PassportModule],
// providers: [AuthService, LocalStrategy],
// })
// export class AuthModule {}
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module'; import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport'; import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy'; import { LocalStrategy } from './local.strategy';
import { JwtModule } from '@nestjs/jwt'; import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants'; import { jwtConstants } from './constants';
import { JwtStrategy } from './jwt.strategy'; import { JwtStrategy } from './jwt.strategy';
@ -28,7 +13,6 @@ import { JwtStrategy } from './jwt.strategy';
PassportModule, PassportModule,
JwtModule.register({ JwtModule.register({
secret: jwtConstants.secret, secret: jwtConstants.secret,
// signOptions: { expiresIn: '60000s' },
}), }),
], ],
providers: [AuthService, LocalStrategy, JwtStrategy], providers: [AuthService, LocalStrategy, JwtStrategy],

View File

@ -1,4 +1,3 @@
export const jwtConstants = { export const jwtConstants = {
// secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
secret: process.env.JWT_SECRET, secret: process.env.JWT_SECRET,
}; };

View File

@ -1,12 +1,7 @@
// import React, { useEffect, useState } from 'react';
import axios from 'axios'; import axios from 'axios';
import { UsersService } from '../users/users.service'; import { UsersService } from '../users/users.service';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { MatchLog } from '../model/user.entity';
@Injectable() @Injectable()
export class loginClass { export class loginClass {
constructor(private readonly usersService: UsersService) {}; constructor(private readonly usersService: UsersService) {};
@ -16,21 +11,18 @@ export class loginClass {
let token = null; let token = null;
let userId = null; let userId = null;
let userName = null; let userName = null;
// let = null;
const params = new URLSearchParams(url.split('?')[1]); const params = new URLSearchParams(url.split('?')[1]);
const code = params.get('code'); const code = params.get('code');
const data = { const data = {
grant_type: 'authorization_code', grant_type: 'authorization_code',
client_id: process.env.CLIENT_UID || 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41', client_id: process.env.CLIENT_UID,
// client_secret: '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',
client_secret: process.env.API_SECRET, client_secret: process.env.API_SECRET,
code: code, code: code,
redirect_uri: process.env.REDIRECT_URI || 'http://' + process.env.REACT_APP_BASE_URL + '/api/auth/login', redirect_uri: process.env.REDIRECT_URI,
}; };
try { try {
const response = await axios.post('https://api.intra.42.fr/oauth/token', data); const response = await axios.post('https://api.intra.42.fr/oauth/token', data);
token = response.data.access_token; token = response.data.access_token;
@ -42,31 +34,25 @@ export class loginClass {
}); });
userName = response2.data.login; userName = response2.data.login;
userId = parseInt(response2.data.id, 10); userId = parseInt(response2.data.id, 10);
// console.log(`all user data= ${response2.data}`)
// const myJSON = JSON.stringify(response2.data);
// console.log(`json version= ${myJSON}`)
} }
catch(error) catch(error)
{ {
console.log(error); console.log(error);
return ; return ;
} }
console.log(`username before serach= ${userName}`)
console.log(`ID before serach= ${userId}`)
let user = await this.usersService.findOne(userName); let user = await this.usersService.findOne(userName);
if (!user) { if (!user) {
console.log(`no user, creating one`);
user = { user = {
id: null, id: null,
partyInvite: null, partyInvite: null,
password: null, password: null,
username: userName, username: userName,
nickname: userName, nickname: userName,
win: 0, win: 0,
loss: 0, loss: 0,
rank: 1200, rank: 1200,
userId: userId, userId: userId,
otp_base32: null, otp_base32: null,
children: null, children: null,
status: 1, status: 1,
// doubleAuth: 0, // doubleAuth: 0,
@ -76,15 +62,11 @@ export class loginClass {
friends: null, friends: null,
blocked: null, blocked: null,
photo: null, photo: null,
sessionNumber: 0,
}; };
await this.usersService.create(user); await this.usersService.create(user);
} }
// console.log(`in login42 user= ${user}`)
const myJSON = JSON.stringify(user); const myJSON = JSON.stringify(user);
console.log(`in login42 user= ${myJSON}`)
console.log("end of login");
return (user); return (user);
// return (await this.usersService.findOne(userName));
} }
} }

View File

@ -1,8 +1,3 @@
// import { Module } from '@nestjs/common';
// @Module({})
// export class ChatModule {}
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { ChatService} from './chat.service'; import { ChatService} from './chat.service';
@ -17,7 +12,6 @@ import { Message } from '../model/chat.entity';
TypeOrmModule.forRoot(getTypeOrmConfig()), TypeOrmModule.forRoot(getTypeOrmConfig()),
TypeOrmModule.forFeature([Conv]), TypeOrmModule.forFeature([Conv]),
TypeOrmModule.forFeature([Message]), TypeOrmModule.forFeature([Message]),
// TypeOrmModule.forFeature([UserRepository]),
], ],
providers:[ChatService], providers:[ChatService],
exports: [ChatService], exports: [ChatService],

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/26 10:17:36 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -15,13 +15,8 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';
import { Conv } from '../model/chat.entity'; import { Conv } from '../model/chat.entity';
import { Message } from '../model/chat.entity'; import { Message } from '../model/chat.entity';
import * as bcrypt from 'bcrypt'; import * as bcrypt from 'bcrypt';
import { ArrayContains } from "typeorm"
import { query } from 'express';
import { InitializeOnPreviewAllowlist } from '@nestjs/core';
@Injectable() @Injectable()
export class ChatService { export class ChatService {
@ -43,13 +38,10 @@ async findAll(): Promise<Conv[]> {
async getConv(username: string): Promise<Conv[]>{ async getConv(username: string): Promise<Conv[]>{
const convs = await this.chatRepository.query("SELECT * FROM \"conv\" WHERE $1 = ANY (ARRAY[members]);", [username]) const convs = await this.chatRepository.query("SELECT * FROM \"conv\" WHERE $1 = ANY (ARRAY[members]);", [username])
console.log(`convs= ${convs}`)
return convs; return convs;
} }
async findConv(number: number){ async findConv(number: number){
// username = "apommier"
console.log(`fincConv; ${number}`)
const conv = await this.chatRepository.findOneBy({id: number}) const conv = await this.chatRepository.findOneBy({id: number})
return conv; return conv;
} }
@ -82,51 +74,67 @@ async findConv(number: number){
async banUser(convId: number, username: string) { async banUser(convId: number, username: string) {
const conv = await this.findConv(convId); const conv = await this.findConv(convId);
if (conv.owner === username)
return (0);
conv.banned = conv.banned || []; conv.banned = conv.banned || [];
if (conv.banned.find(item => item === username)) if (conv.banned.find(item => item === username))
return (1); {
conv.banned = conv.banned.filter((item) => item !== username);
this.save(conv);
return (2);
}
conv.members = conv.members.filter((item) => item !== username); conv.members = conv.members.filter((item) => item !== username);
conv.banned.push(username); conv.banned.push(username);
this.save(conv); this.save(conv);
return (1);
} }
async inviteUser(convId: number, username: string) { async inviteUser(convId: number, username: string) {
// const conv = await this.findConv(convId); const conv = await this.findConv(convId);
// this.save(conv);
//find user if (conv.members.find(item => item === username))
//add in chanInvite chanID return (1);
//save user conv.members.push(username);
this.save(conv);
} }
async setPassword(convId: number, password: string) { async setPassword(convId: number, password: string) {
//verify is user is admin ?
const conv = await this.findConv(convId); const conv = await this.findConv(convId);
const saltRounds = 10; const saltRounds = 10;
const hashedPassword = await bcrypt.hash(password, saltRounds); const hashedPassword = await bcrypt.hash(password, saltRounds);
// return hashedPassword;
conv.password = hashedPassword conv.password = hashedPassword
this.save(conv); this.save(conv);
} }
async verifyPassword(convId: number, password: string) { async verifyPassword(convId: number, password: string, username: string) {
//verify is user is admin ?
const conv = await this.findConv(convId); const conv = await this.findConv(convId);
return await bcrypt.compare(password, conv.password); const ret = await bcrypt.compare(password, conv.password);
if (ret === true)
// conv.password = password {
conv.members = conv.members || [];
conv.members.push(username);
this.save(conv);
}
return ret;
} }
async muteUser(convId: number, username: string) { async muteUser(convId: number, username: string, time: string) {
const conv = await this.findConv(convId); const conv = await this.findConv(convId);
const intTime = parseInt(time) * 1000;
if (conv.owner === username)
return (0);
conv.muted = conv.muted || []; conv.muted = conv.muted || [];
if (conv.muted.find(item => item === username)) if (conv.muted.find(item => item === username))
return (1); return (1);
conv.muted.push(username); conv.muted.push(username);
this.save(conv); this.save(conv);
setTimeout(() => {
conv.muted = conv.muted.filter((item) => item !== username)
this.save(conv);
}, intTime);
} }
async setAdmin(convId: number, username: string) { async setAdmin(convId: number, username: string) {
@ -149,12 +157,10 @@ async isAdmin(convId: number, username: string) {
return (0); return (0);
} }
async setPrivate(convId: number) { async setPrivate(convId: number, bool: boolean) {
const conv = await this.findConv(convId); const conv = await this.findConv(convId);
if (conv.private === true) console.log("bool= ", bool);
conv.private = false; conv.private = bool;
else
conv.private = true;
this.save(conv); this.save(conv);
} }
@ -170,7 +176,6 @@ async joinChannel(convId: number, username: string) {
if (conv.members.find(item => item === username)) if (conv.members.find(item => item === username))
return ; return ;
conv.members.push(username); conv.members.push(username);
// conv.name = name;
this.save(conv); this.save(conv);
} }

View File

@ -3,10 +3,10 @@
/* ::: :::::::: */ /* ::: :::::::: */
/* config.service.ts :+: :+: :+: */ /* config.service.ts :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: sadjigui <sadjigui@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/24 15:09:20 by sadjigui ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */

View File

@ -6,20 +6,11 @@ import * as dotenv from 'dotenv';
dotenv.config(); dotenv.config();
console.log(process.env); console.log(process.env);
// async function bootstrap() {
// const app = await NestFactory.create(AppModule);
// await app.listen(3000);
// }
// bootstrap();
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create(AppModule, { const app = await NestFactory.create(AppModule, {
cors: { cors: {
origin: '*', origin: '*',
methods: '*', methods: '*',
// preflightContinue: false,
// optionsSuccessStatus: 204,
credentials: true, credentials: true,
allowedHeaders: '*', allowedHeaders: '*',
}, },

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/26 06:55:03 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -29,9 +29,6 @@ import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, BaseEntity }
@Column({ nullable: true }) @Column({ nullable: true })
private: boolean private: boolean
// @Column()
// members: string;// arry ??? one to many ???
@Column('text', { array: true, nullable: true }) @Column('text', { array: true, nullable: true })
banned: string[]; banned: string[];
@ -49,18 +46,6 @@ import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, BaseEntity }
@Column({ nullable: true }) @Column({ nullable: true })
messages: string; messages: string;
// @CreateDateColumn()
// createdAt: Date;
//ban user
//user list
//blocked user (in user model ?)
//op list
//a way to stock conv ?
} }
@Entity() @Entity()
@ -77,7 +62,6 @@ import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, BaseEntity }
@Column() @Column()
text: string; text: string;
@CreateDateColumn({ nullable: true }) @CreateDateColumn({ nullable: true })
createdAt?: Date; createdAt?: Date;

View File

@ -20,9 +20,6 @@ export class User {
@PrimaryGeneratedColumn() @PrimaryGeneratedColumn()
id: number; id: number;
// otp_enabled Boolean @default(false)
// otp_verified Boolean @default(false)
@Column({ default: false }) @Column({ default: false })
otp_enabled: boolean; otp_enabled: boolean;
@ -34,7 +31,7 @@ export class User {
@Column({ nullable: true }) @Column({ nullable: true })
nickname: string; nickname: string;
@Column({ nullable: true }) @Column({ nullable: true })
username: string; username: string;
@ -46,31 +43,28 @@ export class User {
@Column({ default: 0 }) @Column({ default: 0 })
win: number; win: number;
@Column({ default: 0 }) @Column({ default: 0 })
loss: number; loss: number;
@Column({ default: 0 })
sessionNumber: number;
@Column({ default: 0 }) @Column({ default: 0 })
rank: number; rank: number;
@Column({ default: 0 }) //0 = offline | 1 = connected | 2 = in game @Column({ default: 0 }) //0 = offline | 1 = connected | 2 = in game
status: number; status: number;
@Column({ default: 0 }) @Column({ default: 0 })
userId: number; userId: number;
// @Column({ default: 0 })
// doubleAuth: number;
@Column('text', { array: true, nullable: true }) @Column('text', { array: true, nullable: true })
friendRequest: string[]; friendRequest: string[];
@Column({ type: 'jsonb', nullable: true }) @Column({ type: 'jsonb', nullable: true })
partyInvite: Record<string, string>[]; 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[];
@ -82,7 +76,7 @@ export class User {
} }
@Entity() @Entity({name: 'MatchLog' })
export class MatchLog { export class MatchLog {
@PrimaryGeneratedColumn() @PrimaryGeneratedColumn()
id: number; id: number;
@ -98,4 +92,4 @@ export class MatchLog {
@ManyToOne(() => User, parent => parent.children) @ManyToOne(() => User, parent => parent.children)
parent: User; parent: User;
} }

View File

@ -1,18 +1,7 @@
// import crypto from 'crypto';
import base32Decode from 'base32-decode';
import crypto from "crypto";
import * as OTPAuth from "otpauth"; import * as OTPAuth from "otpauth";
import { encode } from "hi-base32"; import { encode } from "hi-base32";
import * as qr from 'qrcode'; import * as qr from 'qrcode';
// [...] Register user
// [...] Login user
// [...] Generate OTP
const generateRandomBase32 = async () => { const generateRandomBase32 = async () => {
const {randomBytes} = await import('crypto'); const {randomBytes} = await import('crypto');
const buffer = randomBytes(15); const buffer = randomBytes(15);
@ -36,35 +25,22 @@ export const generateOTP = async (user) => {
let otpauth_url = totp.toString(); let otpauth_url = totp.toString();
const qrCodeDataUrl = await qr.toDataURL(otpauth_url, { errorCorrectionLevel: 'H' }); const qrCodeDataUrl = await qr.toDataURL(otpauth_url, { errorCorrectionLevel: 'H' });
const filePath = 'qrcode.png'; // Specify the file path where the QR code should be saved const filePath = 'qrcode.png';
qr.toFile(filePath, qrCodeDataUrl, (error) => { qr.toFile(filePath, qrCodeDataUrl, (error) => {
if (error) { if (error) {
console.error(error); console.error(error);
// Handle the error appropriately
return; return;
} }
// QR code image has been generated and saved to the file
// Or, you can create a buffer of the image data directly
}) })
const res = { const res = {
otpauth_url: otpauth_url, otpauth_url: otpauth_url,
base32_secret: base32_secret base32_secret: base32_secret
} }
console.log("res= ", res)
//update db with otp var
user.otp_enabled = true; user.otp_enabled = true;
user.otp_base32 = base32_secret; user.otp_base32 = base32_secret;
return (res) return (res);
} catch (error) { } catch (error) {
console.log(error) console.log(error)
} }
@ -84,13 +60,11 @@ export const generateOTP = async (user) => {
let delta = totp.validate({ token }); let delta = totp.validate({ token });
if (delta === null) { if (delta === null) {
console.log("error verify token")
return (0) return (0)
} }
else else
{ {
user.otp_verified = true; user.otp_verified = true;
console.log("token verified")
return (1) return (1)
} }
} catch (error) { } catch (error) {
@ -110,194 +84,11 @@ export const generateOTP = async (user) => {
}); });
let delta = totp.validate({ token }); let delta = totp.validate({ token });
if (delta === null) { if (delta === null)
console.log("error validate token")
return (0); return (0);
}
else else
{
// user.otp_verified = true;
console.log("token validated")
return (1); return (1);
}
} catch (error) { } catch (error) {
console.log(error) console.log(error)
} }
}; };
// import { randomBytes} from 'crypto';
// import { promisify } from 'util';
// export function generateHOTP(secret, counter) {
// const decodedSecret = base32Decode(secret, 'RFC4648');
// const buffer = Buffer.alloc(8);
// for (let i = 0; i < 8; i++)
// {
// buffer[7 - i] = counter & 0xff;
// counter = counter >> 8;
// }
// // Step 1: Generate an HMAC-SHA-1 value
// const hmac = crypto.createHmac('sha1', Buffer.from(decodedSecret));
// hmac.update(buffer);
// const hmacResult = hmac.digest();
// // Step 2: Generate a 4-byte string (Dynamic Truncation)
// const offset = hmacResult[hmacResult.length - 1] & 0xf;
// const code =
// ((hmacResult[offset] & 0x7f) << 24) |
// ((hmacResult[offset + 1] & 0xff) << 16) |
// ((hmacResult[offset + 2] & 0xff) << 8) |
// (hmacResult[offset + 3] & 0xff);
// // Step 3: Compute an HOTP value
// return `${code % 10 ** 6}`.padStart(6, '0');
// }
// type QRcode = any;
// export function generateHOTP(secret, counter) {
// const decodedSecret = base32Decode(secret, 'RFC4648');
// const buffer = Buffer.alloc(8);
// for (let i = 0; i < 8; i++) {
// buffer[7 - i] = counter & 0xff;
// counter = counter >> 8;
// }
// // Step 1: Generate an HMAC-SHA-1 value
// const hmac = crypto.createHmac('sha1', Buffer.from(decodedSecret));
// hmac.update(buffer);
// const hmacResult = hmac.digest();
// // Step 2: Generate a 4-byte string (Dynamic Truncation)
// const offset = hmacResult[hmacResult.length - 1] & 0xf;
// const code =
// ((hmacResult[offset] & 0x7f) << 24) |
// ((hmacResult[offset + 1] & 0xff) << 16) |
// ((hmacResult[offset + 2] & 0xff) << 8) |
// (hmacResult[offset + 3] & 0xff);
// // Step 3: Compute an HOTP value
// return code % 10 ** 6;
// }
// export function generateTOTP(secret, window = 0)
// {
// const counter = Math.floor(Date.now() / 30000);
// return generateHOTP(secret, counter + window);
// }
// export function verifyTOTP(token, secret, window = 1)
// {
// for (let errorWindow = -window; errorWindow <= +window; errorWindow++)
// {
// const totp = generateTOTP(secret, errorWindow);
// if (token === totp)
// return true;
// }
// return false;
// }
// import { initStorage, getUser, setUser } from './storage';
// import util from 'util';
// import qrcode from 'qrcode';
// // import base32Encode from 'base32-encode';
// import * as util from 'util';
// import * as qrcode from 'qrcode';
// import * as base32Encode from 'base32-encode';
// import * as util from 'util';
// import * as qrcode from 'qrcode';
// import * as crypto from 'crypto';
// import { Response } from 'express';
// import { Readable } from 'stream';
// import * as base32Encode from 'base32-encode';
// import { base32Encode } from 'base32-encode';
// import base32Encode from 'base32-encode';
// import { encode } from 'thirty-two';
// // ...
// import * as qrcode from 'qrcode';
// import * as fs from 'fs';
// import { nanoid } from "nanoid";
// // import * as nanoid from 'nanoid'
// export async function generateQRcode(req)
// {
// // const base32Encode = (await import('base32-encode'));
// // const nanoid = (await import('nanoid'));
// // const util = (await import('util'));
// // const qrcode = (await import('qrcode'));
// const user = req.user;
// let res;
// // For security, we no longer show the QR code after is verified
// // if (user.mfaEnabled) return res.status(404).end();
// // if (!user.mfaSecret) { //to do
// const buffer = nanoid(14);
// // generate unique secret for user
// // this secret will be used to check the verification code sent by user
// // const buffer = await util.promisify(crypto.randomBytes)(14);
// // const buffer = crypto.lib.WordArray.random(32)
// user.mfaSecret = encode(buffer).toString('utf8');
// // user.mfaSecret = base32Encoded(buffer, 'RFC4648', { padding: false });
// // setUser(user); // to do !!
// // }
// const issuer = 'Google';
// const algorithm = 'SHA1';
// const digits = '6';
// const period = '30';
// const otpType = 'totp';
// const configUri = `otpauth://${otpType}/${issuer}:${user.username}?algorithm=${algorithm}&digits=${digits}&period=${period}&issuer=${issuer}&secret=${user.mfaSecret}`;
// // res.setHeader('Content-Type', 'image/png');
// const QRCode = require('qrcode');
// console.log(`before done`);
// // QRCode.toFileStream(res, configUri);
// // const filePath = 'qrcode.png'; // Specify the file path where the QR code should be saved
// const qrCodeData = buffer; // Replace with your actual QR code data
// const filePath = 'qrcode.png'; // Specify the file path where the QR code should be saved
// qrcode.toFile(filePath, qrCodeData, (error) => {
// if (error) {
// console.error(error);
// // Handle the error appropriately
// return;
// }
// // QR code image has been generated and saved to the file
// // Or, you can create a buffer of the image data directly
// })
// // qrcode.toFile(filePath, configUri, (error) => {
// // if (error) {
// // console.error(error);
// // // Handle the error appropriately
// // return;
// // }
// // const readableStream = fs.createReadStream(filePath);
// // res.data = readableStream;
// // Use the readable stream as needed
// // });
// // qrcode.toFileStream(res, configUri);
// console.log(`QRcode done`);
// return res;
// // return
// }

View File

@ -11,7 +11,6 @@ import { MatchLog, User } from '../model/user.entity';
TypeOrmModule.forRoot(getTypeOrmConfig()), TypeOrmModule.forRoot(getTypeOrmConfig()),
TypeOrmModule.forFeature([User]), TypeOrmModule.forFeature([User]),
TypeOrmModule.forFeature([MatchLog]), TypeOrmModule.forFeature([MatchLog]),
// TypeOrmModule.forFeature([UserRepository]),
], ],
providers:[UsersService], providers:[UsersService],
exports: [UsersService], exports: [UsersService],

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/26 07:52:08 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -41,12 +41,15 @@ export class UsersService {
return await this.userRepository.findOneBy({username: username}); return await this.userRepository.findOneBy({username: username});
} }
async findNickname(username: string): Promise<User> {
return await this.userRepository.findOneBy({nickname: username});
}
async save(user: User): Promise<User> { async save(user: User): Promise<User> {
return await this.userRepository.save(user); return await this.userRepository.save(user);
} }
async saveChild(user: User, match: MatchLog): Promise<User> { async saveChild(user: User, match: MatchLog): Promise<User> {
// user.match = savedChild;
user.children.push(match) 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);
@ -54,9 +57,7 @@ export class UsersService {
async getFriends(username: string) { async getFriends(username: string) {
const user = await this.findOne(username) const user = await this.findOne(username)
let friendsTab = user.friends let friendsTab = user.friends || [];
console.log(friendsTab)
// friendsTab = ['apommier', 'syd']
const friends = await this.userRepository.query("SELECT * FROM \"User\" WHERE username = ANY ($1);", [friendsTab]); const friends = await this.userRepository.query("SELECT * FROM \"User\" WHERE username = ANY ($1);", [friendsTab]);
console.log(friends) console.log(friends)
return (friends) return (friends)
@ -65,24 +66,21 @@ export class UsersService {
async newInvite(user: User, username: string) { async newInvite(user: User, username: string) {
if (!(await this.findOne(username))) if (!(await this.findOne(username)))
return (0); return (0);
// user.friendRequest = user.friendRequest || [];
// console.log("newInvite")
// console.log(user.friendRequest)
user.friendRequest = user.friendRequest || []; user.friendRequest = user.friendRequest || [];
if (user.friendRequest.find(item => item === username)) if (user.friendRequest.find(item => item === username))
return (1); return (1);
user.friends = user.friends || [];
if (user.friends.find(item => item === username))
return (1);
user.friendRequest.push(username); user.friendRequest.push(username);
this.save(user); this.save(user);
return (1); return (1);
} }
async getInvite(username: string) { async getInvite(username: string) {
const user = await this.findOne(username) const user = await this.findOne(username)
let friendsTab = user.friendRequest let friendsTab = user.friendRequest
// console.log(friendsTab[0])
// console.log(friendsTab[1])
console.log(friendsTab) console.log(friendsTab)
// friendsTab = ['apommier', 'syd']
const friends = await this.userRepository.query("SELECT * FROM \"User\" WHERE username = ANY ($1);", [friendsTab]); const friends = await this.userRepository.query("SELECT * FROM \"User\" WHERE username = ANY ($1);", [friendsTab]);
console.log(friends) console.log(friends)
return (friends) return (friends)
@ -95,28 +93,26 @@ export class UsersService {
async getHistory(username: string) { async getHistory(username: string) {
const user = await this.findOne(username); const user = await this.findOne(username);
if (user) { return await this.userRepository.query("SELECT * FROM \"MatchLog\" WHERE \"parentId\" = ANY ($1);", [[user.id]]);
const children = user.children;
console.log(user);
console.log(user.children); // or perform any operations with the children
return children;
}
} }
async addFriend(user: User, username: string) { async addFriend(user: User, username: string) {
if (!(await this.findOne(username))) const user2 = await this.findOne(username)
if (!user)
return (0); return (0);
// user.friendRequest = user.friendRequest || [];
user.friends = user.friends || []; user.friends = user.friends || [];
if (user.friends.find(item => item === username)) if (user.friends.find(item => item === username))
{ {
user.friendRequest = user.friendRequest.filter((item) => item !== username); user.friendRequest = user.friendRequest.filter((item) => item !== username);
this.save(user); this.save(user);
return (1); return (1);
} }
user.friends.push(username); user.friends.push(username);
user.friendRequest = user.friendRequest.filter((item) => item !== username); user.friendRequest = user.friendRequest.filter((item) => item !== username);
user2.friends = user2.friends || [];
user2.friends.push(user.username);
this.save(user2);
this.save(user); this.save(user);
return (1); return (1);
} }
@ -126,7 +122,11 @@ export class UsersService {
return (0); return (0);
user.blocked = user.blocked || []; user.blocked = user.blocked || [];
if (user.blocked.find(item => item === username)) if (user.blocked.find(item => item === username))
return (1); {
this.save(user);
user.blocked = user.blocked.filter((item) => item !== username);
return (2);
}
user.blocked.push(username); user.blocked.push(username);
this.save(user); this.save(user);
return (1); return (1);
@ -137,40 +137,11 @@ export class UsersService {
} }
async getPic( username: string) { async getPic( username: string) {
// const user = await this.findOne(username);
let result = await this.userRepository.query("select encode(photo, 'base64') FROM public.\"User\" WHERE username = $1;", [username]); let result = await this.userRepository.query("select encode(photo, 'base64') FROM public.\"User\" WHERE username = $1;", [username]);
if (result.length > 0) { if (result.length > 0) {
const encodedPhoto = result[0].encode; const encodedPhoto = result[0].encode;
console.log(`pic!!! =`)
return encodedPhoto; return encodedPhoto;
} }
console.log(`no pic`)
return undefined return undefined
} }
} }
// }
// type orm here
// This should be a real class/interface representing a user entity
// export type User = any;
// @Injectable()
// export class UsersService {
// private readonly users = [
// {
// userId: 1,
// username: 'john',
// password: 'changeme',
// },
// {
// userId: 2,
// username: 'maria',
// password: 'guess',
// },
// ];
// async findOne(username: string): Promise<User | undefined> {
// return this.users.find(user => user.username === username);
// }

View File

@ -8,58 +8,35 @@ 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: 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
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}`);
// console.log(`Client connected: ${args[0].username}`);
// const clientId = args[0].username;
const clientId = client.id; const clientId = client.id;
this.clients[clientId] = client; this.clients[clientId] = client;
// client.emit('chat:clientId', clientId);
console.log(`Total connected clients: ${Object.keys(this.clients).length}`); console.log(`Total connected clients: ${Object.keys(this.clients).length}`);
} }
handleDisconnect(client: Socket) handleDisconnect(client: Socket)
{ {
console.log(`Client want to deco: ${client.id}`);
// const disconnectedClientId = Object.keys(this.clients).find(clientId => this.clients[clientId] === client);
const disconnectedClientId = client.id const disconnectedClientId = client.id
if (disconnectedClientId) if (disconnectedClientId)
{ {
this.clientsNames.forEach((clientArray, clientName) => this.clientsNames.forEach((clientArray, clientName) =>
{ {
// clientArray.
console.log(`Clients with name ${clientName}:`);
console.log(`array= ${clientArray}`)
console.log(`lenght= ${clientArray.length}`)
clientArray.forEach((targetClient, index) => clientArray.forEach((targetClient, index) =>
{ {
console.log(`index= ${index}`)
console.log(`lenght2= ${clientArray.length}`)
if (targetClient === disconnectedClientId) if (targetClient === disconnectedClientId)
{ {
console.log("find it")
console.log(`target= ${clientArray[index]}`)
// delete this.clientsNames[clientName][index];
if (clientArray.length === 1) if (clientArray.length === 1)
{ {
console.log("delete true")
this.clientsNames.delete(clientName); this.clientsNames.delete(clientName);
return return
} }
@ -69,16 +46,11 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
this.clientsNames.delete(clientName); this.clientsNames.delete(clientName);
this.clientsNames.set(clientName, newArray); this.clientsNames.set(clientName, newArray);
} }
//
// this.clientsNames[clientName].delete(index);
// else
return ; return ;
} }
}); });
}); });
delete this.clients[disconnectedClientId]; delete this.clients[disconnectedClientId];
// delete this.clientsNames;
console.log(`Client disconnected: ${disconnectedClientId}`); console.log(`Client disconnected: ${disconnectedClientId}`);
console.log(`Total connected clients: ${Object.keys(this.clients).length}`); console.log(`Total connected clients: ${Object.keys(this.clients).length}`);
} }
@ -86,22 +58,14 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
@SubscribeMessage('connection') @SubscribeMessage('connection')
connectClient(client: any, payload: any): void { connectClient(client: any, payload: any): void {
console.log("connect client")
console.log(`connect name: ${payload.username}`);
if (this.clientsNames.has(payload.username)) { if (this.clientsNames.has(payload.username)) {
console.log("get it") const clientArray = this.clientsNames.get(payload.username);
const clientArray = this.clientsNames.get(payload.username); // Retrieve the array clientArray.push(client.id);
clientArray.push(client.id); // Add the new client to the array
} else { } else {
console.log("create") this.clientsNames.set(payload.username, [client.id]);
this.clientsNames.set(payload.username, [client.id]); // Create a new array with the new client as the value
} }
} }
// @SubscribeMessage('socket.io')
// socketConnect(client: any, payload: any): void {
// console.log("/socket.io")
// }
@SubscribeMessage('ban') @SubscribeMessage('ban')
banUser(client: any, payload: any): void { banUser(client: any, payload: any): void {
@ -113,20 +77,9 @@ banUser(client: any, payload: any): void {
const bannedClients = this.clientsNames.get(payload.username); const bannedClients = this.clientsNames.get(payload.username);
bannedClients.forEach(client => { bannedClients.forEach(client => {
console.log("Banning client:", 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]) console.log("clietn socket=", this.clients[client])
this.clients[client].emit('ban', payload); 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') @SubscribeMessage('mute')
@ -138,51 +91,28 @@ muteUser(client: any, payload: any): void {
} }
const mutedClients = this.clientsNames.get(payload.username); const mutedClients = this.clientsNames.get(payload.username);
mutedClients.forEach(client => { 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); this.clients[client].emit('mute', payload);
}); });
console.log("/mute")
} }
@SubscribeMessage('sendMessage') @SubscribeMessage('sendMessage')
handleMessage(client: Socket, payload: any): void { handleMessage(client: Socket, payload: any): void {
// console.log(`message received: ${payload}`);
// console.log(`message sender: ${payload.sender}`);
// console.log(`client id: ${client.id}`);
// console.log(`conversation ID: ${payload.convId}`);
// console.log(`members: ${payload.members}`);
this.clientsNames.forEach((clientArray, clientName) => this.clientsNames.forEach((clientArray, 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(`target: ${targetClient}`);
// console.log(`target id: ${targetClient}`);
if (targetClient && targetClient !== client.id) if (targetClient && targetClient !== client.id)
{
// console.log("Sending to someone");
// console.log(`index= ${index}`);
// console.log(`target: ${targetClient}`); // Perform actions on each target client
this.clients[targetClient].emit('message', payload) this.clients[targetClient].emit('message', payload)
else
}
else {
console.log("not sending"); console.log("not sending");
}
}); });
} }
}); });
} }
}
}

View File

@ -13,25 +13,18 @@ async function bootstrap() {
cors: { cors: {
origin: '*', origin: '*',
methods: '*', methods: '*',
// preflightContinue: false,
// optionsSuccessStatus: 204,
// credentials: true,
allowedHeaders: '*', allowedHeaders: '*',
}, },
}); });
// const app = await NestFactory.create(AppModule);
const httpServer = app.getHttpServer(); const httpServer = app.getHttpServer();
const io = new socketio.Server(httpServer); const io = new socketio.Server(httpServer);
io.on('connection', (socket) => { io.on('connection', (socket) => {
console.log('Client connected:', socket.id); console.log('Client connected:', socket.id);
// Gestion des événements personnalisés ici
socket.on('customEvent', (data) => { socket.on('customEvent', (data) => {
console.log('Custom event received:', data); console.log('Custom event received:', data);
// Exemple de réponse à un événement personnalisé
socket.emit('customEventResponse', { message: 'Event processed.' }); socket.emit('customEventResponse', { message: 'Event processed.' });
}); });

View File

@ -1,25 +1,5 @@
// import { NestFactory } from '@nestjs/core';
// import { AppModule } from './app.module';
// import * as cors from 'cors';
// async function bootstrap() {
// const app = await NestFactory.create(AppModule);
// app.enableCors({
// origin: 'http://localhost:8080',
// methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
// allowedHeaders: ['Content-Type', 'Authorization'],
// credentials: true,
// });
// await app.listen(3000);
// }
// bootstrap();
import { NestFactory } from '@nestjs/core'; import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module'; import { AppModule } from './app.module';
import * as cors from 'cors';
import { Server } from 'socket.io';
import * as socketio from 'socket.io'; import * as socketio from 'socket.io';
import * as dotenv from 'dotenv'; import * as dotenv from 'dotenv';
@ -31,13 +11,9 @@ async function bootstrap() {
cors: { cors: {
origin: '*', origin: '*',
methods: '*', methods: '*',
// preflightContinue: false,
// optionsSuccessStatus: 204,
// credentials: true,
allowedHeaders: '*', allowedHeaders: '*',
}, },
}); });
// const app = await NestFactory.create(AppModule);
const httpServer = app.getHttpServer(); const httpServer = app.getHttpServer();
const io = new socketio.Server(httpServer); const io = new socketio.Server(httpServer);

View File

@ -6,7 +6,7 @@
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/19 15:18:38 by apommier #+# #+# */ /* Created: 2023/06/19 15:18:38 by apommier #+# #+# */
/* Updated: 2023/06/23 15:19:12 by apommier ### ########.fr */ /* Updated: 2023/06/26 07:04:47 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -28,7 +28,6 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
private clients: Record<string, Socket> = {}; private clients: Record<string, Socket> = {};
private waitingClients: Set<{ client: Socket, option: number }> = new Set(); private waitingClients: Set<{ client: Socket, option: number }> = new Set();
// private waitingClients: Set<Socket> = new Set(); // Utilisateurs cherchant un match
private games: Map<string, Socket[]> = new Map(); // Parties en cours, identifiées par un ID private games: Map<string, Socket[]> = new Map(); // Parties en cours, identifiées par un ID
afterInit(server: Server) afterInit(server: Server)
@ -39,46 +38,31 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
handleConnection(client: Socket, ...args: any[]) handleConnection(client: Socket, ...args: any[])
{ {
console.log(`Client connected: ${client.id}`); console.log(`Client connected: ${client.id}`);
const clientId = client.id; const clientId = client.id;
this.clients[clientId] = client; this.clients[clientId] = client;
// client.emit('pong:clientId', clientId);
client.emit('pong:clientId', client.id); client.emit('pong:clientId', client.id);
console.log(`Total connected clients: ${Object.keys(this.clients).length}`); console.log(`Total connected clients: ${Object.keys(this.clients).length}`);
} }
handleDisconnect(client: Socket) handleDisconnect(client: Socket)
{ {
console.log(`Normal disconnected: ${client.id}`);
this.waitingClients.forEach((item) => { this.waitingClients.forEach((item) => {
if (item.client === client) if (item.client === client)
this.waitingClients.delete(item); this.waitingClients.delete(item);
}); });
// Delete the socket from the 'games' map
this.games.forEach((sockets, gameId) => { this.games.forEach((sockets, gameId) => {
const index = sockets.indexOf(client); const index = sockets.indexOf(client);
if (index !== -1) if (index !== -1)
{ {
if (index === 0) if (index === 0)
{
console.log("emit boy1")
sockets[1].emit("pong:win") sockets[1].emit("pong:win")
// sockets[0].emit("/win")
}
else else
{
console.log("emit boy2")
sockets[0].emit("pong:win") sockets[0].emit("pong:win")
// sockets[1].emit("/win")
}
this.games.delete(gameId); 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}`);
} }
@ -91,29 +75,19 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
if (this.clients.hasOwnProperty(key) && this.clients[key] === client) if (this.clients.hasOwnProperty(key) && this.clients[key] === client)
delete this.clients[key]; delete this.clients[key];
} }
// Delete the socket from the 'waitingClients' set
this.waitingClients.forEach((item) => { this.waitingClients.forEach((item) => {
if (item.client === client) if (item.client === client)
this.waitingClients.delete(item); this.waitingClients.delete(item);
}); });
// Delete the socket from the 'games' map
this.games.forEach((sockets, gameId) => { this.games.forEach((sockets, gameId) => {
const index = sockets.indexOf(client); const index = sockets.indexOf(client);
if (index !== -1) if (index !== -1)
{ {
if (index === 0) if (index === 0)
{
console.log("emit boy1")
sockets[1].emit("pong:win") sockets[1].emit("pong:win")
// sockets[0].emit("/win")
}
else else
{
console.log("emit boy2")
sockets[0].emit("pong:win") sockets[0].emit("pong:win")
// sockets[1].emit("/win")
}
this.games.delete(gameId); this.games.delete(gameId);
delete this.clients[client.id]; delete this.clients[client.id];
} }
@ -129,29 +103,18 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
@SubscribeMessage('pong:matchmaking') @SubscribeMessage('pong:matchmaking')
addMatchmaking(client: Socket, payload: any): void { addMatchmaking(client: Socket, payload: any): void {
console.log("matchmaking");
console.log(payload);
console.log(`option= ${payload.option}`);
// Add the client to the waitingClients set along with their chosen option
this.waitingClients.add({ client, option: payload.option }); this.waitingClients.add({ client, option: payload.option });
console.log("Adding client to waiting list..."); console.log("Adding client to waiting list...");
// Filter the waitingClients set to find clients with the same option
const matchingClients = Array.from(this.waitingClients).filter( const matchingClients = Array.from(this.waitingClients).filter(
(waitingClient) => (waitingClient) =>
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];
players.forEach((player) => { players.forEach((player) => {
// this.waitingClients.delete(
// this.waitingClients.find(
// (waitingClient) => waitingClient.client === player
// )
// );
const matchingClient = Array.from(this.waitingClients).find( const matchingClient = Array.from(this.waitingClients).find(
(waitingClient) => waitingClient.client === player (waitingClient) => waitingClient.client === player
); );
@ -165,12 +128,11 @@ addMatchmaking(client: Socket, payload: any): void {
player.join(gameId); player.join(gameId);
console.log(`Player ${player.id} joined game ${gameId}`); console.log(`Player ${player.id} joined game ${gameId}`);
}); });
payload.gameId = gameId;
players.forEach((player) => { players.forEach((player) => {
player.emit('pong:gameId', gameId); player.emit('pong:gameId', payload);
}); });
} }
// console.log(`from: ${client.id}`);
} }
@ -182,48 +144,27 @@ addMatchmaking(client: Socket, payload: any): void {
//======================================================================================================== //========================================================================================================
// @SubscribeMessage('pong:invite')
// createPrivateGame(client: Socket, payload: any): void {
// //after invite accepted ?
// //set the two user in a game ?
// }
@SubscribeMessage('pong:joinParty') @SubscribeMessage('pong:joinParty')
joinPrivateParty(client: Socket, payload: any): void { joinPrivateParty(client: Socket, payload: any): void {
console.log(" join PrivateParty")
const game = this.games.get(payload.gameId); const game = this.games.get(payload.gameId);
if (game) if (game)
{ {
game.push(client); game.push(client);
const playersIds = game.map(socket => socket.id); const playersIds = game.map(socket => socket.id);
this.clients[playersIds[0]].emit('pong:gameId', payload.gameId); this.clients[playersIds[0]].emit('pong:gameId', payload);
this.clients[playersIds[1]].emit('pong:gameId', payload.gameId); this.clients[playersIds[1]].emit('pong:gameId', payload);
} }
else else
{
console.log("emit else")
client.emit("pong:win") client.emit("pong:win")
}
// console.log("no game ???")
} }
@SubscribeMessage('pong:privateParty') @SubscribeMessage('pong:privateParty')
addPrivateParty(client: Socket, payload: any): void { addPrivateParty(client: Socket, payload: any): void {
console.log("addPrivateParty")
const gameId = uuidv4(); const gameId = uuidv4();
const players = [client]; const players = [client];
this.games.set(gameId, players); this.games.set(gameId, players);
console.log("game created private")
client.emit('pong:privateId', gameId); client.emit('pong:privateId', gameId);
//create game
//emit private gameId to canvas (don't launch canvas)
} }
@ -244,7 +185,6 @@ addPrivateParty(client: Socket, payload: any): void {
sendPower(client: Socket, payload: any): void sendPower(client: Socket, payload: any): void
{ {
console.log(`from: ${client.id}`); console.log(`from: ${client.id}`);
console.log(payload);
const game = this.games.get(payload.gameId); const game = this.games.get(payload.gameId);
const playersIds = game.map(socket => socket.id); const playersIds = game.map(socket => socket.id);
@ -252,14 +192,12 @@ addPrivateParty(client: Socket, payload: any): void {
this.clients[playersIds[1]].emit('pong:power', payload); this.clients[playersIds[1]].emit('pong:power', payload);
else if (playersIds[1] === payload.id) else if (playersIds[1] === payload.id)
this.clients[playersIds[0]].emit('pong:power', payload); this.clients[playersIds[0]].emit('pong:power', payload);
console.log("END OF HANDLE");
} }
@SubscribeMessage('pong:message') @SubscribeMessage('pong:message')
handleMessage(client: Socket, payload: any): void handleMessage(client: Socket, payload: any): void
{ {
console.log(`from: ${client.id}`); console.log(`from: ${client.id}`);
console.log(payload);
const game = this.games.get(payload.gameId); const game = this.games.get(payload.gameId);
const playersIds = game.map(socket => socket.id); const playersIds = game.map(socket => socket.id);
@ -273,20 +211,14 @@ addPrivateParty(client: Socket, payload: any): void {
if (payload.ballX < payload.width / 2) if (payload.ballX < payload.width / 2)
this.clients[playersIds[0]].emit('pong:info', payload); this.clients[playersIds[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
{ {
console.log(`from: ${client.id}`);
console.log(payload);
const game = this.games.get(payload.gameId); const game = this.games.get(payload.gameId);
const playersIds = game.map(socket => socket.id); const playersIds = game.map(socket => socket.id);
console.log(`id of 0= ${playersIds[0]}`);
if (playersIds[0] === payload.id) if (playersIds[0] === payload.id)
{ {
this.clients[playersIds[1]].emit('pong:info', payload); this.clients[playersIds[1]].emit('pong:info', payload);
@ -295,20 +227,13 @@ addPrivateParty(client: Socket, payload: any): void {
{ {
this.clients[playersIds[0]].emit('pong:info', payload); this.clients[playersIds[0]].emit('pong:info', payload);
} }
console.log("END OF HANDLE");
} }
@SubscribeMessage('pong:paddle') @SubscribeMessage('pong:paddle')
handlePaddle(client: Socket, payload: any): void handlePaddle(client: Socket, payload: any): void
{ {
console.log(`from: ${client.id}`);
console.log(payload);
const game = this.games.get(payload.gameId); const game = this.games.get(payload.gameId);
const playersIds = game.map(socket => socket.id); const playersIds = game.map(socket => socket.id);
console.log(`id of 0= ${playersIds[0]}`);
if (playersIds[0] === payload.id) if (playersIds[0] === payload.id)
{ {
this.clients[playersIds[1]].emit('pong:paddle', payload); this.clients[playersIds[1]].emit('pong:paddle', payload);
@ -317,7 +242,6 @@ addPrivateParty(client: Socket, payload: any): void {
{ {
this.clients[playersIds[0]].emit('pong:paddle', payload); this.clients[playersIds[0]].emit('pong:paddle', payload);
} }
console.log("END OF HANDLE");
} }
@SubscribeMessage('pong:point') @SubscribeMessage('pong:point')
@ -337,21 +261,32 @@ addPrivateParty(client: Socket, payload: any): void {
} }
} }
@SubscribeMessage('pong:myPoint')
handleMyPoint(client: Socket, payload: any): void
{
const game = this.games.get(payload.gameId);
const playersIds = game.map(socket => socket.id);
console.log(`id of 0 mypoint= ${playersIds[0]}`);
if (playersIds[0] === payload.id)
this.clients[playersIds[1]].emit('pong:hisPoint', payload);
else if (playersIds[1] === payload.id)
this.clients[playersIds[0]].emit('pong:hisPoint', payload);
}
@SubscribeMessage('pong:name') @SubscribeMessage('pong:name')
getName(client: Socket, payload: any): void getName(client: Socket, payload: any): void
{ {
const game = this.games.get(payload.gameId); const game = this.games.get(payload.gameId);
const playersIds = game.map(socket => socket.id); const playersIds = game.map(socket => socket.id);
console.log(`name of client= ${payload.name}`); console.log(`name of client= ${payload.name}`);
if (playersIds[0] === payload.id)
if (playersIds[0] === payload.id)
{ {
this.clients[playersIds[1]].emit('pong:name', payload.name); this.clients[playersIds[1]].emit('pong:name', payload);
} }
if (playersIds[1] === payload.id) if (playersIds[1] === payload.id)
{ {
this.clients[playersIds[0]].emit('pong:name', payload.name); this.clients[playersIds[0]].emit('pong:name', payload);
} }
} }

View File

@ -1,5 +1,14 @@
REACT_APP_BASE_URL=localhost:8080 REACT_APP_BASE_URL=localhost:8080
REACT_APP_SOCKET_URL=localhost
REACT_APP_API_SECRET=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 REACT_APP_API_SECRET=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
REACT_APP_CLIENT_UID=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41 REACT_APP_CLIENT_UID=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41
# REACT_APP_BASE_URL=92.143.191.152 # REACT_APP_BASE_URL=92.143.191.152
# REACT_APP_BASE_URL=192.168.1.19 # REACT_APP_BASE_URL=192.168.1.19
REACT_APP_INTRA_URL="https://api.intra.42.fr/oauth/authorize?client_id=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fapi%2Fauth%2Flogin&response_type=code"
# REACT_APP_BASE_URL=92.143.191.152
# REACT_APP_BASE_URL=192.168.1.19

View File

@ -16,6 +16,7 @@ export interface User {
partyInvite: Record<string, string>[]; partyInvite: Record<string, string>[];
friends: string[]; friends: string[];
blocked: string[]; blocked: string[];
sessionNumber: number;
} }
export interface Conv { export interface Conv {

View File

@ -22,7 +22,7 @@
"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=8081 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",

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -2,14 +2,10 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<meta <link rel="shortcut icon" type="image/jpeg" href="/favicon.jpeg"/>
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!-- <!--
manifest.json provides metadata used when your web app is installed on a manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
@ -24,10 +20,8 @@
work correctly both with client-side routing and a non-root public URL. work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`. Learn how to configure a non-root public URL by running `npm run build`.
--> -->
<title>React App</title>
</head> </head>
<body> <body >
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root" style=" height: 100%;"></div> <div id="root" style=" height: 100%;"></div>
<!-- <!--
This HTML file is a template. This HTML file is a template.

View File

@ -1,58 +0,0 @@
export const Rank = [
{
rank: '1',
name: 'jean',
},
{
rank: '2',
name: 'marc',
},
{
rank: '3',
name: 'dujardain',
},
{
rank: '4',
name: 'mom',
},
{
rank: '5',
name: 'fary',
},
{
rank: '6',
name: 'aba',
},
{
rank: '7',
name: 'preach',
},
{
rank: '1',
name: 'jean',
},
{
rank: '2',
name: 'marc',
},
{
rank: '3',
name: 'dujardain',
},
{
rank: '4',
name: 'mom',
},
{
rank: '5',
name: 'fary',
},
{
rank: '6',
name: 'aba',
},
{
rank: '7',
name: 'preach',
},
]

View File

@ -1,8 +0,0 @@
import DefaultPic from '../assets/profile.jpg';
export const UserProfile = {
Pic: DefaultPic,
UserName: 'Dipper Ratman',
}
// export default UserProfile

View File

@ -1,37 +0,0 @@
export const DBWinLoss = [
{
title: 'Victory',
score: '10 - 6',
opponent: 'chef bandit'
},
{
title: 'Defeat',
score: '9 - 10',
opponent: 'ex tueur'
},
{
title: 'Victory',
score: '10 - 0',
opponent: 'tueur'
},
{
title: 'Victory',
score: '10 - 9',
opponent: 'boulanger'
},
{
title: 'Defeat',
score: '3 - 10',
opponent: 'charcutier'
},
{
title: 'Deafet',
score: '9 - 10',
opponent: 'preach'
},
{
title: 'Victory',
score: '10 - 9',
opponent: 'aba'
},
]

View File

@ -7,26 +7,27 @@ import React from "react";
const dropIn = { const dropIn = {
hidden: { hidden: {
y: "-100vh", y: "-100vh",
}, },
visible: { visible: {
y: "0", y: "0",
}, },
exit: { exit: {
y: "-100vh", y: "-100vh",
}, },
}; };
interface AlertProps { interface AlertProps {
handleClose: Function, handleClose: Function,
text: string text: string
} }
function GreenAlert ({handleClose, text}: AlertProps){ function GreenAlert({ handleClose, text }: AlertProps) {
{ setTimeout(handleClose, 1500) }
return( return (
<Backdrop onClick={handleClose}>
<motion.div <Backdrop onClick={handleClose}>
<motion.div
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
className="greenAlert" className="greenAlert"
// variant={dropIn} // variant={dropIn}
@ -34,10 +35,11 @@ function GreenAlert ({handleClose, text}: AlertProps){
animate="visible" animate="visible"
exit="exit" exit="exit"
> >
<AiOutlineCheckCircle/> <AiOutlineCheckCircle />
<p>{text}</p> <div className="text_alert">
<h5>{text}</h5>
</div>
</motion.div> </motion.div>
{setTimeout(handleClose, 1500)}
</Backdrop> </Backdrop>
) )
} }

View File

@ -23,6 +23,7 @@ interface AlertProps {
} }
function RedAlert ({handleClose, text}: AlertProps) { function RedAlert ({handleClose, text}: AlertProps) {
{setTimeout(handleClose, 1500)}
return( return(
<Backdrop onClick={handleClose}> <Backdrop onClick={handleClose}>
<motion.div <motion.div
@ -32,11 +33,12 @@ function RedAlert ({handleClose, text}: AlertProps) {
initial="hidden" initial="hidden"
animate="visible" animate="visible"
exit="exit" exit="exit"
> >
<BiErrorCircle/> <BiErrorCircle/>
<p>{text}</p> <div className="text_alert">
<h5>{text}</h5>
</div>
</motion.div> </motion.div>
{setTimeout(handleClose, 1500)}
</Backdrop> </Backdrop>
) )
} }

View File

@ -8,26 +8,27 @@ import { GiCrownedSkull, GiWingedSword } from "react-icons/gi";
const dropIn = { const dropIn = {
hidden: { hidden: {
y: "-100vh", y: "-100vh",
}, },
visible: { visible: {
y: "0", y: "0",
}, },
exit: { exit: {
y: "-100vh", y: "-100vh",
}, },
}; };
interface AlertProps { interface AlertProps {
handleClose: Function, handleClose: Function,
text: string, text: string,
icon: number icon: number
} }
function YellowAlert ({handleClose, text, icon}: AlertProps) { function YellowAlert({ handleClose, text, icon }: AlertProps) {
return( { setTimeout(handleClose, 3000) }
return (
<Backdrop onClick={handleClose}> <Backdrop onClick={handleClose}>
<motion.div <motion.div
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
className="yellowAlert" className="yellowAlert"
// variant={dropIn} // variant={dropIn}
@ -36,24 +37,25 @@ function YellowAlert ({handleClose, text, icon}: AlertProps) {
exit="exit" exit="exit"
> >
{icon === 0 ? ( {icon === 0 ? (
<GrTrophy/> <GrTrophy />
):("")} ) : ("")}
{icon === 1 ? ( {icon === 1 ? (
<MdQrCodeScanner/> <MdQrCodeScanner />
):("")} ) : ("")}
{icon === 2 ? ( {icon === 2 ? (
<GiCrownedSkull/> <GiCrownedSkull />
):("")} ) : ("")}
{icon === 3 ? (
<GiWingedSword/>
):("")}
<h5>{text}</h5> {icon === 3 ? (
<GiWingedSword />
) : ("")}
<div className="text_alert">
<h5>{text}</h5>
</div>
</motion.div> </motion.div>
{setTimeout(handleClose, 3000)}
</Backdrop> </Backdrop>
) )
} }

View File

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

View File

@ -1,16 +1,15 @@
import React from "react"; import React, { useEffect } from "react";
import {Routes, Route, Navigate} from 'react-router-dom'; import { Routes, Route, Navigate } from 'react-router-dom';
import HomeLogin from "../pages/Home.js"; import HomeLogin from "../pages/LoginButton.tsx";
import Home from "../pages/Home.tsx"; import Home from "../pages/Home.tsx";
import PlayButton from "./Game/PlayButton.tsx"; import PlayButton from "./Game/PlayButton.tsx";
import Field from "../pages/Field.tsx"; import Field from "../pages/Field.tsx";
import Login42 from "../pages/Login42.tsx";
import Messages from "../pages/Messages.tsx"; import Messages from "../pages/Messages.tsx";
import QrCode from '../pages/QrCode.tsx' import QrCode from '../pages/QrCode.tsx'
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import {AnimatePresence} from "framer-motion"; import { AnimatePresence } from "framer-motion";
import SuccessToken from '../script/tokenSuccess.tsx' import SuccessToken from '../script/tokenSuccess.tsx'
@ -19,53 +18,71 @@ import DoubleAuth from "../pages/2fa.tsx";
import Game from "../pages/Game.tsx"; import Game from "../pages/Game.tsx";
import Social from "./Social/Social.tsx"; import Social from "./Social/Social.tsx";
import Logout from "./Profile/Logout.tsx"; import Logout from "./Profile/Logout.tsx";
import api from "../script/axiosApi.tsx"
function AnimatedRoute() {
useEffect(() => {
const handleBeforeUnload = async (event: { preventDefault: () => void; returnValue: string; }) => {
console.log("git ")
if (!localStorage.getItem('token'))
return;
try {
await api.post("/quit");
} catch (err) {
console.log(err);
}
};
const handleLoad = async () => {
if (!localStorage.getItem('token'))
return;
try {
await api.post("/addSession");
} catch (err) {
console.log(err);
}
};
handleLoad();
window.addEventListener('beforeunload', handleBeforeUnload);
return () => {
window.removeEventListener('beforeunload', handleBeforeUnload);
};
}, []);
function AnimatedRoute () {
// const location = useLocation();
const location = useLocation(); const location = useLocation();
if (!localStorage.getItem('token')) if (!localStorage.getItem('token')) {
{
return ( return (
<AnimatePresence> <AnimatePresence>
<Routes location={location} key={location.pathname}> <Routes location={location} key={location.pathname}>
<Route path="/" element={<HomeLogin/>}/> <Route path="/" element={<HomeLogin />} />
<Route path="/token" element={<SuccessToken />}/> <Route path="/token" element={<SuccessToken />} />
</Routes>
{/* <Route path="/404" element={<HomeLogin/>} /> */} </AnimatePresence>
{/* <Route path="*" element={<Navigate to="/404" />} /> */}
</Routes>
</AnimatePresence>
) )
} }
return ( return (
<AnimatePresence> <AnimatePresence>
<Routes location={location} key={location.pathname}> <Routes location={location} key={location.pathname}>
<Route path="/" element={<Home />} />
{/* <Route path="/login" element={<HomeLogin/>}/> */} <Route path="/profile" element={<Home />} />
<Route path="/" element={<Home/>}/> <Route path="/profile/:username" element={<Home />} />
<Route path="/profile" element={<Home/>}/> <Route path="/qr" element={<QrCode />} />
<Route path="/profile/:username" element={<Home/>}/> <Route path="/2fa" element={<DoubleAuth />} />
<Route path="/qr" element={<QrCode/>}/> <Route path="/Social" element={<Social />} />
<Route path="/token" element={<SuccessToken />} />
<Route path="/2fa" element={<DoubleAuth/>}/> <Route path="/game" element={<PlayButton />} />
<Route path="/Social" element={<Social/>}/> <Route path="/pong" element={<Game />} />
<Route path="/pong/play" element={<Field />} />
<Route path="/token" element={<SuccessToken />}/> <Route path="/logout" element={<Logout />} />
<Route path="/game" element={<PlayButton />}/> <Route path="/messages" element={<Messages />} />
<Route path="/pong" element={<Game />}/>
<Route path="/pong/play" element={<Field />}/>
{/* <Route path="/profile" element={<PlayButton />}/> */}
<Route path="/login42" element={<Login42 />}/>
<Route path="/logout" element={<Logout />}/>
<Route path="/messages" element={<Messages />}/>
<Route path="/404" element={<PageNotFound />} /> <Route path="/404" element={<PageNotFound />} />
<Route path="*" element={<Navigate to="/404" />} /> <Route path="*" element={<Navigate to="/404" />} />
</Routes> </Routes>
</AnimatePresence> </AnimatePresence>
) )
} }
export default AnimatedRoute export default AnimatedRoute

View File

@ -1,35 +1,23 @@
import React from 'react'; import React from 'react';
import '../../styles/field.css'; import '../../styles/field.css';
// import { useHistory } from 'react-router-dom';
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
function PlayButton() { function PlayButton() {
const history = useNavigate(); const history = useNavigate();
// const handleButtonClick = () => {
// let path = `play`;
// history(path);
// };
const handleButtonClick = () => { const handleButtonClick = () => {
let path = `play?`; let path = `play?`;
const superpowerCheckbox = document.querySelector<HTMLInputElement>('input[value="superpower"]'); const superpowerCheckbox = document.querySelector<HTMLInputElement>('input[value="superpower"]');
if (superpowerCheckbox && superpowerCheckbox.checked) { if (superpowerCheckbox && superpowerCheckbox.checked) {
path += 'superpower=true&'; path += 'superpower=true&';
} }
const obstacleCheckbox = document.querySelector<HTMLInputElement>('input[value="obstacle"]');
if (obstacleCheckbox && obstacleCheckbox.checked) {
path += 'obstacle=true&';
}
const speedCheckbox = document.querySelector<HTMLInputElement>('input[value="speed"]'); const speedCheckbox = document.querySelector<HTMLInputElement>('input[value="speed"]');
if (speedCheckbox && speedCheckbox.checked) { if (speedCheckbox && speedCheckbox.checked) {
path += 'speed=true&'; path += 'speed=true&';
} }
// Remove the trailing '&' character
path = path.slice(0, -1); path = path.slice(0, -1);
console.log(path) console.log(path)
history(path); history(path);
@ -40,12 +28,11 @@ function PlayButton() {
<button onClick={handleButtonClick} className="playButton">Play</button> <button onClick={handleButtonClick} className="playButton">Play</button>
{/* !buttonClicked && <button onClick={handleButtonClick}>Draw on Canvas</button> */} {/* !buttonClicked && <button onClick={handleButtonClick}>Draw on Canvas</button> */}
<div className='checkbox'> <div className='checkbox'>
<p><input type="checkbox" value="superpower"/> Super Power </p> <p><input className="inside_checkbox" type="checkbox" value="superpower"/> Super Power <br/> ( w = wall power ) </p>
<p><input type="checkbox" value="obstacle"/> Obstacle </p> <p><input className="inside_checkbox" type="checkbox" value="speed"/> Faster and Faster </p>
<p><input type="checkbox" value="speed"/> Faster and Faster </p>
</div> </div>
</div> </div>
); );
} }
export default PlayButton; export default PlayButton;

View File

@ -6,7 +6,7 @@
/* 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/23 17:16:40 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -41,7 +41,7 @@ function Rank({user, index}: RankProps){
}; };
fetchProfilePicture(); fetchProfilePicture();
}) }, [])
// console.log(index); // console.log(index);
return ( return (

View File

@ -21,18 +21,15 @@ function Ranking(){
// setFriends(tmpFriends.data); // setFriends(tmpFriends.data);
// return tmpUser; // return tmpUser;
// console.log(`user= ${tmpUser.data.username}`); // console.log(`user= ${tmpUser.data.username}`);
setIsLoading(false) setIsLoading(false);
} }
catch(err){ catch(err){
console.log(err); console.log(err);
} }
}; };
getRanking(); getRanking();
}, []);
}, []) console.log(`ranking after= ${ranking}`);
console.log(`ranking after= ${ranking}`)
return ( return (
<div> <div>

View File

@ -2,14 +2,12 @@ import React, { useState, useEffect, useRef } from "react";
import io, { Socket } from 'socket.io-client'; import io, { Socket } 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 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 GameModal from "./GameModal.tsx";
import Message from "./Message.tsx" import Message from "./Message.tsx"
// import Input from "./Input";
//react icons //react icons
import { TbSend } from 'react-icons/tb'; import { TbSend } from 'react-icons/tb';
@ -17,16 +15,15 @@ import { ImBlocked } from 'react-icons/im';
import { MdOutlineGroupAdd } from 'react-icons/md'; 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 { HiChatBubbleLeft } from 'react-icons/hi2'
// 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 ModalSetting from "./ModalSetting.tsx"; import ModalSetting from "./ModalSetting.tsx";
import PartyInvite from "./PartyInvite.tsx"; import PartyInvite from "./PartyInvite.tsx";
// import {User, Conv, Message} from "../../../interfaces.tsx"
import {User, Conv} from "../../../interfaces.tsx" import {User, Conv} from "../../../interfaces.tsx"
import { IoLogoOctocat } from "react-icons/io5";
const TouchDiv = styled.div` const TouchDiv = styled.div`
margin-left: 10px; margin-left: 10px;
@ -35,7 +32,7 @@ const TouchDiv = styled.div`
margin-top: 21px; margin-top: 21px;
cursor: pointer; cursor: pointer;
justify-content: space-around; justify-content: space-around;
&:hover { &:hover {
color: #F4F3EF; color: #F4F3EF;
} }
@ -57,11 +54,6 @@ const UserChat = styled.div `
} }
` `
// const SideSpan = styled.span`
// font-size: 18px;
// font-weight: 500;
// `
const SideP = styled.p` const SideP = styled.p`
font-size: 14px; font-size: 14px;
color: lightgray; color: lightgray;
@ -70,7 +62,7 @@ const SideP = styled.p`
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// Logical part // Logical part
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
@ -90,16 +82,12 @@ function Chats(){
const [user, setUser] = useState<User>(); const [user, setUser] = useState<User>();
const [currentChat, setCurrentChat] = useState<Conv>(); // false is good? const [currentChat, setCurrentChat] = useState<Conv>(); // false is good?
const [isAdmin, setIsAdmin] = useState<boolean>(false); // false is good? const [isAdmin, setIsAdmin] = useState<boolean>(false); // false is good?
// const [currentChat, setCurrentChat] = useState(false); // false is good?
const [messages, setMessage] = useState<MessageProps[]>([]); const [messages, setMessage] = useState<MessageProps[]>([]);
const [newMessages, setNewMessage] = useState(""); const [newMessages, setNewMessage] = useState("");
const [incomingMessage, setIncomingMessage] = useState<MessageProps>(); const [incomingMessage, setIncomingMessage] = useState<MessageProps>();
// let socket: Socket;
const socket = useRef<Socket | null>(null); const socket = useRef<Socket | null>(null);
// const socket = Socket<DefaultEventsMap, DefaultEventsMap> | null
// socket = useRef( useRef<SocketIOClient.Socket | null>(null));
useEffect(()=> { useEffect(()=> {
@ -112,62 +100,50 @@ function Chats(){
console.log(convs); console.log(convs);
// console.log("invite data use effect= ", tmpInvite.data);
setPartyInvite(tmpInvite.data); setPartyInvite(tmpInvite.data);
setUser(tmpUser.data); setUser(tmpUser.data);
setConversation(convs.data); setConversation(convs.data);
setUsers(tmpUsers.data); setUsers(tmpUsers.data);
// console.log(`connection....`); socket.current = io('http://' + process.env.REACT_APP_SOCKET_URL + ':4001', { transports: ['polling'] });
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 ?)
setIncomingMessage(data); setIncomingMessage(data);
}); });
socket.current.on('ban', (data) => { socket.current.on('ban', (data) => {
// setIncomingMessage(data);
console.log("banned hehe");
window.location.reload() window.location.reload()
}); });
socket.current.on('mute', (data) => { // socket.current.on('mute', (data) => {
console.log("muted hehe"); // console.log("muted hehe");
//set mute var to true and do nothing // //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 () => { return () => {
console.log("Cleanup");
if (socket.current) if (socket.current)
socket.current.disconnect(); socket.current.disconnect();
// cleanup(); // Call the cleanup function to stop the ongoing process or perform necessary cleanup tasks
// cleanup();
}; };
}, []) }, [])
useEffect(()=> { useEffect(()=> {
const updateChat = async ()=> { const updateChat = async ()=> {
// if (currentChat)
// console.log(currentChat.id)
if (currentChat) if (currentChat)
{ {
try { try {
const res = await api.post("/isAdmin", {convId: currentChat.id}) const res = await api.post("/isAdmin", {convId: currentChat.id})
console.log("isadmin= ", res.data)
setIsAdmin(res.data); setIsAdmin(res.data);
} catch (err) { } catch (err) {
console.log(err); console.log(err);
@ -175,19 +151,13 @@ 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 && incomingMessage && currentChat.id === incomingMessage.convId)
{ setMessage((prev) => [...prev, incomingMessage]);
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]);
}
} }
updateChat(); updateChat();
}, [incomingMessage, currentChat]) }, [incomingMessage, currentChat])
useEffect(()=> { useEffect(()=> {
const getMessage = async ()=> const getMessage = async ()=>
{ {
if (!currentChat) if (!currentChat)
@ -196,7 +166,6 @@ function Chats(){
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,11 +174,8 @@ function Chats(){
getMessage(); getMessage();
}, [currentChat]); }, [currentChat]);
const handleSubmit = async (e: { preventDefault: () => void; })=>{ const handleSubmit = async (e: { key?: any; preventDefault: any; })=>{
e.preventDefault(); e.preventDefault();
// console.log(`e= ${e.key}`)
// console.log(`name= ${user.username}`)
// let message;
if (!user || !currentChat) if (!user || !currentChat)
return ; return ;
const message = { const message = {
@ -221,13 +187,8 @@ function Chats(){
}; };
try{ try{
const allowed = await api.post('/allowed', {convId: currentChat.id}); const allowed = await api.post('/allowed', {convId: currentChat.id});
console.log("convid:", currentChat.id);
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;
@ -236,96 +197,64 @@ function Chats(){
setNewMessage(""); setNewMessage("");
if (socket.current) if (socket.current)
socket.current.emit('sendMessage', message); socket.current.emit('sendMessage', message);
} }
catch(err){ catch(err){
console.log(err) console.log(err)
} }
} }
const handleKeyPress = async (e: { key: string; })=> { const handleKeyPress = async (e: { key?: any; preventDefault: () => void; })=> {
// console.log(`e in press= ${e.key}`)
if (e.key !== "Enter") if (e.key !== "Enter")
return ; return ;
// console.log(`name= ${user.username}`) handleSubmit(e);
if (!user || !currentChat)
return ;
const message = {
sender: user.username,
text: newMessages,
convId: currentChat.id,
members: null,
id: null,
};
try{
const res = await api.post('/message', message);
const convMember = await api.post('/member', message);
message.members = convMember.data.members;
message.id = res.data.id
setMessage([...messages, res.data]);
setNewMessage("");
if (socket.current)
socket.current.emit('sendMessage', message);
}
catch(err){
console.log(err)
}
} }
const [friend, setFriend] = useState(""); const [friend, setFriend] = useState("");
// 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);
const [showAddFriendAlert, setShowAddFriendAlert] = useState(false); const [showAddFriendAlert, setShowAddFriendAlert] = useState(false);
const [showBlockAlert, setShowBlockAlert] = useState(false); const [showBlockAlert, setShowBlockAlert] = useState(false);
const [setting, setSetting] = useState(false); const [setting, setSetting] = useState(false);
const [newGameModalOpen, setNewGameModalOpen] = useState(false); const [newGameModalOpen, setNewGameModalOpen] = useState(false);
const [newConversationModalOpen, setNewConversationModalOpen] = useState(false); const [newConversationModalOpen, setNewConversationModalOpen] = useState(false);
const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]); const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
const [users, setUsers] = useState<User[]>([]); const [users, setUsers] = useState<User[]>([]);
const [unblock, setUnblock] = useState(false);
const closeUnblock = () => setUnblock(false);
const openNewGameModal = () => { const openNewGameModal = () => {
setNewGameModalOpen(true); setNewGameModalOpen(true);
}; };
const closeNewGameModal = () => { const closeNewGameModal = () => {
setNewGameModalOpen(false); setNewGameModalOpen(false);
}; };
const openNewConversationModal = () => { const openNewConversationModal = () => {
setNewConversationModalOpen(true); setNewConversationModalOpen(true);
}; };
const closeNewConversationModal = () => { const closeNewConversationModal = () => {
setNewConversationModalOpen(false); setNewConversationModalOpen(false);
}; };
// const close = () => setModalOpen(false);
// const open = () => setModalOpen(true);
// const closeAddFriend = () => setAddFriend(false);
// const closeBlock = () => setBlock(false);
const closeSetting = () => setSetting(false); const closeSetting = () => setSetting(false);
// const closeAddFriend = () => setAddFriend(false);
// const closeBlock = () => setBlock(false);
const handleFriend = (event: { target: { value: React.SetStateAction<string>; }; }) => { const handleFriend = (event: { target: { value: React.SetStateAction<string>; }; }) => {
setFriend(event.target.value); setFriend(event.target.value);
}; };
const handleAddFriend = async () => { const handleAddFriend = async () => {
try{ try{
console.log("friend= ", friend);
const res = await api.post("/invite", {username: friend}) const res = await api.post("/invite", {username: friend})
// if (res.data === 1)
// console.log("res in friend= ", res)
console.log("res in friend= ", res.data) console.log("res in friend= ", res.data)
if(res.data === 1) if(res.data === 1)
{ {
@ -340,15 +269,18 @@ function Chats(){
console.log(err) console.log(err)
} }
}; };
const handleBlockFriend = async () => { const handleBlockFriend = async () => {
try{ try{
const res = await api.post("/block", {username: friend}) const res = await api.post("/block", {username: friend})
// if(1) // if(1)
if (res.data === 2)
setUnblock(true);
if (res.data === 1) if (res.data === 1)
{ {
setBlock(true); setBlock(true);
setAddFriend(false); // Reset addFriend state setAddFriend(false);
setShowAddFriendAlert(false); setShowAddFriendAlert(false);
} }
else else
@ -358,12 +290,12 @@ function Chats(){
console.log(err) console.log(err)
} }
}; };
const closeAddFriend = () => { const closeAddFriend = () => {
setAddFriend(false); setAddFriend(false);
setShowAddFriendAlert(false); setShowAddFriendAlert(false);
}; };
const closeBlock = () => { const closeBlock = () => {
setBlock(false); setBlock(false);
setShowBlockAlert(false); setShowBlockAlert(false);
@ -371,7 +303,8 @@ function Chats(){
const handleOptionChange = (selectId: number, selectedOption: string) => { const handleOptionChange = (selectId: number, selectedOption: string) => {
console.log("selected Option=", selectedOption) console.log("selected Option=", selectedOption)
setSelectTag((prevTags) => setFriend(selectedOption);
setSelectTag((prevTags) =>
prevTags.map((tag) => prevTags.map((tag) =>
tag.id === selectId ? { ...tag, selectedOption } : tag tag.id === selectId ? { ...tag, selectedOption } : tag
) )
@ -380,67 +313,23 @@ function Chats(){
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// HTML // HTML
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
return ( return (
<div className="chat"> <div className="chat">
<div className='navbar'> <div className='navbar'>
<img src={DefaultPic} alt="profile" className="pic"/> <IoLogoOctocat className="catchat"/>
<span> <span>
{isLoading || !user ? ( {isLoading || !user ? (
<h4>Loading...</h4> <h4>Loading...</h4>
) : ( ) : (
<h4>{user.nickname}</h4> <h2>Chat</h2>
)} )}
</span> </span>
{/* <div className="end">
<input className="lookForFriends" type="text" value={friend} onChange={handleFriend}/>
<TouchDiv>
<motion.div
onClick={() => (addFriend ? setAddFriend(false) : setAddFriend(true))}>
<MdOutlineGroupAdd/>
</motion.div>
<AnimatePresence
initial={false}
onExitComplete={() => null}
>
{addFriend && <GreenAlert handleClose={closeAddFriend} text={friend + " was successfuly added"}/>}
</AnimatePresence>
</TouchDiv>
<TouchDiv>
<motion.div
onClick={() => (block ? setBlock(false) : setBlock(true))}
>
<ImBlocked/>
<AnimatePresence
initial={false}
onExitComplete={() => null}
>
{block && <RedAlert handleClose={closeBlock} text={friend + " was successfuly blocked"}/>}
</AnimatePresence>
</motion.div>
</TouchDiv>
{currentChat ? (
<TouchDiv>
<motion.div
onClick={() => (setting ? setSetting(false) : setSetting(true))}
>
<RiListSettingsLine/>
<AnimatePresence
initial={false}
onExitComplete={() => null}
>
{setting && <ModalSetting handleClose={closeSetting} convId={currentChat.id}/>}
</AnimatePresence>
</motion.div>
</TouchDiv>
):("")}
</div> */}
<div className="end"> <div className="end">
{selectTags.map((selectTag) => ( {selectTags.map((selectTag) => (
@ -451,11 +340,11 @@ function Chats(){
onChange={(a) => handleOptionChange(selectTag.id, a.target.value)} onChange={(a) => handleOptionChange(selectTag.id, a.target.value)}
> >
<option value="">{ <option value="">{
selectTag.selectedOption ? selectTag.selectedOption : "Select an option" selectTag.selectedOption ? selectTag.selectedOption : "Select a user"
}</option> }</option>
{users.filter((item) => !selectTags.some((tag) => tag.selectedOption === item.username)).map((item, index) => ( {users.filter((item) => !selectTags.some((tag) => tag.selectedOption === item.username)).map((item, index) => (
<option key={index} value={item.username}> <option key={index} value={item.username}>
{item.username} {item.nickname}
</option> </option>
))} ))}
</select> </select>
@ -463,7 +352,7 @@ function Chats(){
))} ))}
<TouchDiv> <TouchDiv>
<motion.div onClick={handleAddFriend}> <motion.div onClick={handleAddFriend}>
<MdOutlineGroupAdd /> <MdOutlineGroupAdd className="catchat"/>
</motion.div> </motion.div>
<AnimatePresence initial={false} onExitComplete={() => null}> <AnimatePresence initial={false} onExitComplete={() => null}>
{showAddFriendAlert && addFriend && ( {showAddFriendAlert && addFriend && (
@ -476,7 +365,7 @@ function Chats(){
</TouchDiv> </TouchDiv>
<TouchDiv> <TouchDiv>
<motion.div onClick={handleBlockFriend}> <motion.div onClick={handleBlockFriend}>
<ImBlocked /> <ImBlocked className="block"/>
</motion.div> </motion.div>
<AnimatePresence initial={false} onExitComplete={() => null}> <AnimatePresence initial={false} onExitComplete={() => null}>
{showBlockAlert && block && ( {showBlockAlert && block && (
@ -485,14 +374,17 @@ function Chats(){
{showBlockAlert && !block && ( {showBlockAlert && !block && (
<RedAlert handleClose={closeBlock} text={friend + ' was not found'} /> <RedAlert handleClose={closeBlock} text={friend + ' was not found'} />
)} )}
{unblock ? (
<GreenAlert handleClose={closeUnblock} text={friend + ' was unblocked'} />
):("")}
</AnimatePresence> </AnimatePresence>
</TouchDiv> </TouchDiv>
{currentChat && isAdmin ? ( {currentChat && isAdmin ? (
<TouchDiv> <TouchDiv>
<motion.div <motion.div
onClick={() => (setting ? setSetting(false) : setSetting(true))} onClick={() => (setting ? setSetting(false) : setSetting(true))}
> >
<RiListSettingsLine/> <RiListSettingsLine className="block"/>
<AnimatePresence <AnimatePresence
initial={false} initial={false}
onExitComplete={() => null} onExitComplete={() => null}
@ -527,13 +419,6 @@ function Chats(){
)} )}
</UserChat> </UserChat>
{/* {partyInvite.map((c) => {
return (
)})
} */}
{partyInvite.map( i =>( {partyInvite.map( i =>(
<PartyInvite currentInvite={i}/> <PartyInvite currentInvite={i}/>
))} ))}
@ -543,14 +428,14 @@ function Chats(){
<div key={index} <div key={index}
onClick={() => setCurrentChat(c)}> onClick={() => setCurrentChat(c)}>
<UserChat> <UserChat>
<img className="pic-user" src={DefaultPic} alt="User" /> <HiChatBubbleLeft className="catchat"/>
<div className="infoSideBar"> <div className="infoSideBar">
<span>{c.name}</span> <h2>{c.name}</h2>
{/* <SideP>Desc?</SideP> */} {/* <SideP>Desc?</SideP> */}
</div> </div>
</UserChat> </UserChat>
</div> </div>
)})} )})}
</div> </div>
@ -563,7 +448,6 @@ function Chats(){
<Message key={m.id} message= {m} own={m.sender === user.username}/> <Message key={m.id} message= {m} own={m.sender === user.username}/>
))} ))}
</div> </div>
{/* <Input/> */}
<div className="input"> <div className="input">
<input <input
onKeyDown={handleKeyPress} onKeyDown={handleKeyPress}
@ -571,7 +455,7 @@ function Chats(){
placeholder="What do you want to say" placeholder="What do you want to say"
onChange={(e) => setNewMessage(e.target.value)} onChange={(e) => setNewMessage(e.target.value)}
value={newMessages} value={newMessages}
/> />
<div className="send"> <div className="send">
<TbSend onClick={handleSubmit}></TbSend> <TbSend onClick={handleSubmit}></TbSend>
</div> </div>
@ -585,8 +469,7 @@ function Chats(){
)} )}
</div> </div>
</div> </div>
// </div> );
);
} }
export default Chats export default Chats

View File

@ -79,11 +79,7 @@ const GameModal = ({ handleClose }: ModalGame) => {
path += 'superpower=true&'; path += 'superpower=true&';
} }
const obstacleCheckbox = document.querySelector<HTMLInputElement>('input[value="obstacle"]');
if (obstacleCheckbox && obstacleCheckbox.checked) {
path += 'obstacle=true&';
}
const speedCheckbox = document.querySelector<HTMLInputElement>('input[value="speed"]'); const speedCheckbox = document.querySelector<HTMLInputElement>('input[value="speed"]');
if (speedCheckbox && speedCheckbox.checked) { if (speedCheckbox && speedCheckbox.checked) {
path += 'speed=true&'; path += 'speed=true&';
@ -122,7 +118,7 @@ const GameModal = ({ handleClose }: ModalGame) => {
<option value="">Select a user</option> <option value="">Select a user</option>
{users.map((user: User) => ( {users.map((user: User) => (
<option key={user.id} value={user.username}> <option key={user.id} value={user.username}>
{user.username} {user.nickname}
</option> </option>
))} ))}
</select> </select>
@ -132,10 +128,9 @@ const GameModal = ({ handleClose }: ModalGame) => {
{/* <button onClick={handleButtonClick}>Draw on Canvas</button> */} {/* <button onClick={handleButtonClick}>Draw on Canvas</button> */}
<div className='checkbox'> <div className='checkbox'>
<p><input type="checkbox" value="superpower"/> Super Power </p> <p><input type="checkbox" value="superpower"/> Super Power </p>
<p><input type="checkbox" value="obstacle"/> Obstacle </p>
<p><input type="checkbox" value="speed"/> Faster and Faster </p> <p><input type="checkbox" value="speed"/> Faster and Faster </p>
</div> </div>
<button className="submit" onClick={handleButtonClick} >Play</button> <button className="playInvite" onClick={handleButtonClick} >Play</button>
{/* <button className="submit" onClick={handleClose}>Cancel</button> */} {/* <button className="submit" onClick={handleClose}>Cancel</button> */}
</div> </div>

View File

@ -6,7 +6,7 @@
/* 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/25 23:24:46 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -23,9 +23,9 @@ import React from "react";
const MeStyleP = styled.p` const MeStyleP = styled.p`
background-color: #5843e4; background-color: #5843e4;
padding 10px 20px; padding 10px 20px;
border-radius 10px 0px 10px 10px; border-radius 10px;
color: white; color: white;
margin-right: 20px; margin: 10px;
` `
interface MessageMeProps { interface MessageMeProps {
@ -34,23 +34,24 @@ interface MessageMeProps {
} }
function MessageMe({message, own}: MessageMeProps){ function MessageMe({message, own}: MessageMeProps){
const [profilePicture, setProfilePicture] = useState(''); const [profilePicture, setProfilePicture] = useState('');
const [sender, setSender] = useState<User>(); const [sender, setSender] = useState<User>();
const [conv, setConv] = useState<Conv>(); const [conv, setConv] = useState<Conv>();
const [user, setUser] = useState<User>(); const [user, setUser] = useState<User>();
const scrollRef = useRef<HTMLDivElement>(null); const scrollRef = useRef<HTMLDivElement>(null);
// console.log("Message eher")
useEffect(() => { useEffect(() => {
if (scrollRef.current) if (scrollRef.current)
{ {
scrollRef.current.scrollIntoView({ behavior: "smooth",}) scrollRef.current.scrollIntoView({ behavior: "smooth"});
} }})
useEffect(() => {
const fetchProfilePicture = async () => { const fetchProfilePicture = async () => {
try { try {
console.log("useEffect message")
// const user = await api.get("/profile"); // const user = await api.get("/profile");
const tmpSender = await api.post("/user", {username: message.sender}) const tmpSender = await api.post("/user", {username: message.sender})
const tmpConv = await api.post("/convId", {convId: message.convId}) const tmpConv = await api.post("/convId", {convId: message.convId})
@ -68,7 +69,7 @@ function MessageMe({message, own}: MessageMeProps){
} }
}; };
fetchProfilePicture(); fetchProfilePicture();
}, []) }, []);
const handleButtonClick = () => { const handleButtonClick = () => {
if (!sender) if (!sender)
@ -81,23 +82,37 @@ function MessageMe({message, own}: MessageMeProps){
window.location.reload(); window.location.reload();
}; };
// const isAllowed = async () => {
// const ret = await api.post("/allowed", {convId: message.convId});
// return ret.data;
// }
if (!user || !sender || !conv) if (!user || !sender || !conv)
{
// console.log("return")
return (<></>); return (<></>);
}
// console.log("result includes=", conv.banned.includes(user.username)) // console.log("result includes=", conv.banned.includes(user.username))
// console.log("result includes=", conv.blocked.includes(user.username)) // console.log("result includes=", conv.blocked.includes(user.username))
// const conv2: Conv = getConv();
// if (!conv)
// isAllowed().then((ret: number) => {
// if (!ret)
// {
// console.log("return not allowed");
// return ;
// }
// // Use the resolved currentConv here
// });
if (user.blocked && user.blocked.includes(message.sender)) if (user.blocked && user.blocked.includes(message.sender))
return (<></>); return (<></>);
// else if (conv.banned && conv.banned.includes(user.username)) else if (conv.banned && conv.banned.includes(user.username))
// { return (<></>);
// console.log("return2") else if (conv.muted && conv.muted.includes(user.username))
// return (<></>); {
// } // console.log("muted00")
// console.log("noy return") return (<></>);
}
// if (user.blocked.includes(message.sender))/ // if (user.blocked.includes(message.sender))/
console.log("no return message good");
return ( return (
<div className={own ? "meMessage" : "youMessage"} ref={scrollRef}> <div className={own ? "meMessage" : "youMessage"} ref={scrollRef}>
<div> <div>
@ -115,8 +130,8 @@ function MessageMe({message, own}: MessageMeProps){
<MeStyleP>{message.text}</MeStyleP> <MeStyleP>{message.text}</MeStyleP>
</div> </div>
</div> </div>
) )
} }
export default MessageMe export default MessageMe

View File

@ -7,6 +7,7 @@ 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 React from "react";
import {User, Conv} from "../../../interfaces.tsx"
const dropIn = { const dropIn = {
hidden:{y:"-100vh", hidden:{y:"-100vh",
@ -21,21 +22,22 @@ const dropIn = {
}}, }},
exit:{y: "100vh", exit:{y: "100vh",
opacity: 0,}, opacity: 0,},
}; };
const Modal = ({handleClose}) => { interface ModalProps {
// const [multi, setMulti] = useState(false); handleClose: Function,
}
const Modal = ({handleClose}: ModalProps) => {
const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]); const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
const [selectedOptionArray, setSelectedOptionArray] = useState([]); const [selectedOptionArray, setSelectedOptionArray] = useState<string[]>([]);
const [users, setUsers] = useState([]); const [users, setUsers] = useState<User[]>([]);
const [user, setUser] = useState(); const [user, setUser] = useState<User>();
const [convs, setConvs] = useState([]); const [convs, setConvs] = useState<Conv[]>([]);
const [channel, setChannel] = useState(''); const [channel, setChannel] = useState('');
useEffect(()=> { useEffect(()=> {
const getConv = async ()=>{ const getConv = async ()=>{
try { try {
const tmpUsers = await api.get("/users"); const tmpUsers = await api.get("/users");
@ -46,16 +48,55 @@ const Modal = ({handleClose}) => {
setUsers(tmpUsers.data); setUsers(tmpUsers.data);
setUser(tmpUser.data); setUser(tmpUser.data);
setConvs(tmpConvs.data); setConvs(tmpConvs.data);
} catch(err){ } catch(err) {
console.log(err) console.log(err)
} }
} }
getConv(); getConv();
}, []); }, []);
const handleOptionChange = (selectId, selectedOption) => { const [askPass, setAskPass] = useState(false);
const [PassWord, setPassWord] = useState('');
useEffect(()=> {
const getConv = async ()=>{
console.log("chan changed")
console.log("chan = ", channel);
try{
const tmpConv = await api.post("/convId", {convId: channel});
if (tmpConv.data.password)
setAskPass(true);
}
catch(err){
console.log(err);
}
// if (channel.password)
// console.log("password true")
// else
// console.log("password false")
}
getConv();
}, [channel]);
const handlePassword = async (e: { key: string; }) => {
if (e.key !== "Enter")
return;
try {
const ret = await api.post("/verifyPassword", {convId: channel, password: PassWord})
if (ret)
console.log("ici ret password", ret);
// window.location.reload();
} catch (err) {
console.log(err);
}
handleClose();
}
const handleOptionChange = (selectId: number, selectedOption: string) => {
console.log("selected Option=", selectedOption) console.log("selected Option=", selectedOption)
setSelectTag((prevTags) => setSelectTag((prevTags) =>
prevTags.map((tag) => prevTags.map((tag) =>
tag.id === selectId ? { ...tag, selectedOption } : tag tag.id === selectId ? { ...tag, selectedOption } : tag
) )
@ -71,18 +112,19 @@ const Modal = ({handleClose}) => {
const joinChannel = async () => { const joinChannel = async () => {
try { try {
console.log("channel= ", channel) console.log("channel= ", channel)
console.log("ici test channel= ", channel)
await api.post("/join", {convId: channel}) await api.post("/join", {convId: channel})
window.location.reload();
} catch(err) { } catch(err) {
console.log(err); console.log(err);
} }
}; };
const saveSelectedOptions = async () => { const saveSelectedOptions = async () => {
// 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 !== '');
console.log("selected= ", selectedOptions); console.log("selected= ", selectedOptions);
//do db stuff here
const data = { const data = {
members: selectedOptions, members: selectedOptions,
} }
@ -97,30 +139,30 @@ const Modal = ({handleClose}) => {
setSelectedOptionArray(selectedOptions); setSelectedOptionArray(selectedOptions);
} }
// let new_name;
return ( return (
<Backdrop onClick={handleClose}> <Backdrop onClick={handleClose}>
<motion.div <motion.div
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
className="modal" className="modalSetting"
// variant={dropIn}
initial="hidden" initial="hidden"
animate="visible" animate="visible"
exit="exit" exit="exit"
> >
<div className="settingFirstPart2">
{selectTags.map((selectTag) => ( {selectTags.map((selectTag) => (
<div key={selectTag.id}> <div key={selectTag.id}>
<select <select
value={selectTag.selectedOption} value={selectTag.selectedOption}
onChange={(a) => handleOptionChange(selectTag.id, a.target.value)} onChange={(a) => handleOptionChange(selectTag.id, a.target.value)}
> >
<option value="">{ <option value="">{
selectTag.selectedOption ? selectTag.selectedOption : "Select an option" selectTag.selectedOption ? selectTag.selectedOption : "Select a user"
}</option> }</option>
{users.filter((item) => !selectTags.some((tag) => tag.selectedOption === item.name)).map((item, index) => ( {users.filter((item) => !selectTags.some((tag) => tag.selectedOption === item.nickname)).map((item, index) => (
<option key={index} value={item.username}> <option key={index} value={item.username}>
{item.username} {item.nickname}
</option> </option>
))} ))}
</select> </select>
@ -130,43 +172,44 @@ const Modal = ({handleClose}) => {
<GrAdd onClick={addNewSelectedTag}/> <GrAdd onClick={addNewSelectedTag}/>
</div> </div>
<div className="div_submit"> <div className="div_submit">
<Link to='#' className="submit" onClick={ saveSelectedOptions}>Submit</Link> <Link to='#' className="submit" onClick={saveSelectedOptions}>Submit</Link>
</div>
<Link to="#" className="submit" onClick={handleClose}>Cancel</Link>
</div> </div>
<div className="settingSecondPart">
{convs.length > 0 && ( {convs.length > 0 && (
<select <select
value={channel} value={channel}
onChange={(event) => setChannel(event.target.value)} onChange={(event) => setChannel(event.target.value)}
> >
<option value="">Select an option</option> <option value="">Select a channel</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 && user && conv.banned.includes(user.username)) || (conv.members && user && 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>
) )
))} ))}
</select> </select>
)} )}
{channel.private ? (
<input className="mdp" placeholder="password" type="text" /> <div>
):("")}
{askPass ? (
<input className="mdp" placeholder="password" type="password" onChange={(e) => setPassWord(e.target.value)} onKeyDown={handlePassword}/>
):("") }
</div>
<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>
</div>
</motion.div> </motion.div>
</Backdrop> </Backdrop>
) )
} }
export default Modal export default Modal

View File

@ -1,31 +1,13 @@
import { motion } from "framer-motion"; import { AnimatePresence, motion } from "framer-motion";
import Backdrop from "../Sidebar/Backdrop.tsx"; import Backdrop from "../Sidebar/Backdrop.tsx";
// 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 { 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 React from "react";
import {User} from "../../../interfaces.tsx" import { User } from "../../../interfaces.tsx"
import { Socket } from "socket.io-client"; import { Socket } from "socket.io-client";
import GreenAlert from "../Alert/GreenAlert.tsx";
const dropIn = {
hidden:{y:"-100vh",
opacity: 0,},
visible:{y: "0",
opacity: 0,
transotion:{
duration:0.1,
type:"spring",
damping: 100,
stiffness: 500,
}},
exit:{y: "100vh",
opacity: 0,},
};
interface ModalSettingProps { interface ModalSettingProps {
handleClose: Function, handleClose: Function,
@ -33,14 +15,16 @@ interface ModalSettingProps {
socket: Socket | null, socket: Socket | null,
} }
const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => { 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<User[]>([]);
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 [time, setTime] = useState("");
const [newPassword, setNewPassword] = useState(""); const [newPassword, setNewPassword] = useState("");
const [privateConv, setPrivateConv] = useState(false); const [privateConv, setPrivateConv] = useState<Boolean>();
const [loading, setLoading] = useState<Boolean>(true);
const dark = () => setPrivateConv(true); const dark = () => setPrivateConv(true);
const light = () => setPrivateConv(false); const light = () => setPrivateConv(false);
const [mute, setMute] = useState(false); const [mute, setMute] = useState(false);
@ -48,218 +32,237 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
const lightMute = () => setMute(true); const lightMute = () => setMute(true);
useEffect(()=> { useEffect(() => {
console.log("convid =", convId) console.log("convid =", convId)
const getUsers = async ()=>{ const getUsers = async () => {
try { try {
const currentConv = await api.post("/convId", { convId: convId });
if (currentConv.data.private)
setPrivateConv(true);
const tmpUsers = await api.get("/users"); const tmpUsers = await api.get("/users");
console.log("users=", tmpUsers.data); console.log("users=", tmpUsers.data);
setUsers(tmpUsers.data); setUsers(tmpUsers.data);
} catch(err){ setLoading(false);
} catch (err) {
console.log(err) console.log(err)
} }
} }
getUsers(); getUsers();
}, []); }, []);
// const [multi, setMulti] = useState(false); useEffect(() => {
// const [selectedOptionArray, setSelectedOptionArray] = useState([]); const handleVariableChange = () => {
console.log('Variable changed:', privateConv);
if (privateConv === undefined) {
console.log("return")
return;
}
try {
if (privateConv)
api.post("/private", { convId: convId })
else
api.post("/public", { convId: convId })
} catch (err) {
console.log(err);
}
};
if (!loading)
handleVariableChange();
}, [privateConv]);
const handleOptionChange = (selectId: number, selectedOption: string) => {
const handleOptionChange = (selectId: number, selectedOption: string) => {
console.log("tag= ", selectTags) console.log("tag= ", selectTags)
console.log("option= ", selectedOption) console.log("option= ", selectedOption)
setSelectTag((prevTags) => setSelectTag((prevTags) =>
prevTags.map((tag) => prevTags.map((tag) =>
tag.id === selectId ? { ...tag, selectedOption } : tag tag.id === selectId ? { ...tag, selectedOption } : tag
) )
); );
setSelectedUser(selectedOption) setSelectedUser(selectedOption)
}; };
const handleCheckPass = (e: { target: { checked: boolean | ((prevState: boolean) => boolean); }; }) => { const handleCheckPass = (e: { target: { checked: boolean | ((prevState: boolean) => boolean); }; }) => {
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 handleName = async (e: { key: string; }) => {
// setPassword(e.target.checked);
if (e.target.checked)
{
console.log("chack true", e.target.checked)
try{
api.post("/private", {convId: convId})
} catch(err) {
console.log(err);
}
}
else
{
console.log("chack false", e.target.checked)
try{
api.post("/private", {convId: convId})
} catch(err) {
console.log(err);
}
}
}
const handleName = async (e: { key: string; })=>{
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() 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: { key: string; }) => {
if (e.key !== "Enter") if (e.key !== "Enter")
return ; return;
try{ try {
await api.post("/password", {convId: convId, password: newPassword}) await api.post("/password", { convId: convId, password: newPassword })
} catch(err) { } catch (err) {
console.log(err); console.log(err);
} }
handleClose(); handleClose();
} }
const handleBan = async () => { const [unban, setUnban] = useState(false);
// console.log("ban option= ", selectedUser) const closeUnban = () => setUnban(false);
try{
// console.log("user select=", selectedUser.length) const handleBan = async () => {
try {
if (!selectedUser.length) if (!selectedUser.length)
return ; return;
await api.post("/ban", {convId: convId, username: selectedUser}) const res = await api.post("/ban", { convId: convId, username: selectedUser })
if (socket) console.log("res of ban", res.data)
{
console.log("emit to ban server") if (res.data === 2) {
socket.emit("ban", {username: selectedUser}) console.log("hehe true");
setUnban(true);
} }
} catch(err) { if (socket) {
console.log("emit to ban server")
socket.emit("ban", { username: selectedUser })
}
} catch (err) {
console.log(err); console.log(err);
} }
handleClose(); setTimeout(handleClose, 1500);
}; };
const handleAdmin = async () => { const handleAdmin = async () => {
if (!selectedUser.length) if (!selectedUser.length)
return ; return;
try{ try {
await api.post("/admin", {convId: convId, username: selectedUser}) await api.post("/admin", { convId: convId, username: selectedUser })
} catch(err) { } catch (err) {
console.log(err); console.log(err);
} }
handleClose(); handleClose();
}; };
const handleMute = async () => { const [muteAlert, setMuteAlert] = useState(false);
if (!selectedUser.length) const closeMuteAlert = () => setMuteAlert(false);
return ;
try{ const handleMute = async (e: { key: string; }) => {
await api.post("/mute", {convId: convId, username: selectedUser}) console.log(`e in press= ${e.key}`)
} catch(err) { if (e.key != "Enter")
return;
console.log("value mute = ", time);
try {
const ret = await api.post("/mute", { convId: convId, username: selectedUser, time: time })
if (ret.data)
setMuteAlert(true);
} catch (err) {
console.log(err); console.log(err);
} }
handleClose(); handleClose();
}; };
const handleInvite = async () => { const handleInvite = async () => {
try{ try {
await api.post("/invite", {convId: convId, username: selectedUser}) console.log("post invite bitch");
} catch(err) { await api.post("/inviteConv", { convId: convId, username: selectedUser });
} catch (err) {
console.log(err); console.log(err);
} }
handleClose(); handleClose();
}; };
return ( return (
<Backdrop onClick={handleClose}> <Backdrop onClick={handleClose}>
<motion.div <motion.div
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
className="modalSetting" className="modalSetting"
initial="hidden" initial="hidden"
animate="visible" animate="visible"
exit="exit" exit="exit"
> >
<div className="settingFirstPart">
{/* First selection */} <div>
<div className="settingFirstPart">
<div>
<div> <div>
<Link to="#" onClick={light} className={ privateConv ? "submit" : "darkSubmit"}>Public</Link> <Link to="#" onClick={light} className={privateConv ? "submit" : "darkSubmit"}>Public</Link>
<Link to="#" onClick={dark} className={ privateConv ? "darkSubmit" : "submit"}>Private</Link> <Link to="#" onClick={dark} className={privateConv ? "darkSubmit" : "submit"}>Private</Link>
</div> </div>
{/* <p className="checkbox">Private<input className="check"type="checkbox" value="private" onChange={handleCheckPriv}/></p> */} <p className="checkbox">Password<input className="inside_ckeckbox" type="checkbox" value="password" checked={password} onChange={handleCheckPass} /> </p>
<p className="checkbox">Password<input type="checkbox" value="password" checked={password} onChange={handleCheckPass}/> </p> {password ? (
<input
{password || privateConv ? (
<input
onChange={(e) => setNewPassword(e.target.value)} onChange={(e) => setNewPassword(e.target.value)}
onKeyDown={handlePassword} onKeyDown={handlePassword}
type="password" type="password"
className="in" className="in"
placeholder="Password"/> placeholder="Password" />
): ) :
("")} ("")}
</div>
</div> <div className="forName">
<div className="forName"> <input
<input
onChange={(e) => setNewName(e.target.value)} onChange={(e) => setNewName(e.target.value)}
onKeyDown={handleName} onKeyDown={handleName}
type="text" maxLength={20}
className="in" type="text"
className="in"
placeholder="New Name" placeholder="New Name"
/> />
</div> </div>
</div> </div>
{/* Second selection */} <div className="settingSecondPart">
<div className="settingSecondPart">
{selectTags.map((selectTag) => ( {selectTags.map((selectTag) => (
<div key={selectTag.id}> <div key={selectTag.id}>
<select <select
value={selectTag.selectedOption} value={selectTag.selectedOption}
onChange={(a) => handleOptionChange(selectTag.id, a.target.value)} onChange={(a) => handleOptionChange(selectTag.id, a.target.value)}
> >
<option value=""> <option value="">
{selectTag.selectedOption ? selectTag.selectedOption : "Select an option"} {selectTag.selectedOption ? selectTag.selectedOption : "Select an option"}
</option> </option>
{users.map((item, index) => ( {users.map((item, index) => (
<option key={index} value={item.username}> <option key={index} value={item.username}>
{item.username} {item.nickname}
</option> </option>
))} ))}
</select> </select>
</div> </div>
))} ))}
<div>
<Link to="#" onClick={handleInvite} className="submit">Invite</Link>
<Link to="#" onClick={handleBan} className="submit">Ban</Link>
<Link to="#" onClick={mute ? darkMute : lightMute} className={mute ? "darkSubmit" : "submit"}>Mute</Link>
<Link to="#" onClick={handleAdmin} className="submit">Admin</Link>
</div>
<div> </div>
<Link to="#" onClick={handleInvite} className="submit">Send</Link> {mute ? (
<Link to="#" onClick={handleBan} className="submit">Ban</Link> <input
<Link to="#" onClick={mute ? darkMute : lightMute} className={mute ? "darkSubmit": "submit"}>Mute</Link> onKeyDown={handleMute}
<Link to="#" onClick={handleAdmin} className="submit">Admin</Link> type="number"
</div> className="in_howLong"
placeholder="Time"
value={time}
onChange={(e) => setTime(e.target.value)}
/>
) : ("")}
<AnimatePresence initial={false} onExitComplete={() => null}>
{unban ? (
<GreenAlert handleClose={closeUnban} text={selectedUser + ": was unbanned"} />
) : ("")}
{muteAlert ? (
<GreenAlert handleClose={closeMuteAlert} text="Mute" />
) : ("")}
</AnimatePresence>
</div> </motion.div>
{mute ? ( </Backdrop>
<input type="text" className="in_howLong" placeholder="How long ?" /> )
):("")}
</motion.div>
</Backdrop>
)
} }
export default ModalSetting export default ModalSetting

View File

@ -1,12 +1,13 @@
import {motion} from "framer-motion" import { AnimatePresence, motion } from "framer-motion"
// import Backdrop from "../Sidebar/Backdrop" // import Backdrop from "../Sidebar/Backdrop"
import {Link} from 'react-router-dom'; import { Link } from 'react-router-dom';
import { UserProfile } from "../../DataBase/DataUserProfile"; // import { UserProfile } from "../../DataBase/DataUserProfile";
import {useState} from 'react'; import { useState } from 'react';
import "../../styles/Profile.css" import "../../styles/Profile.css"
import api from '../../script/axiosApi.tsx'; import api from '../../script/axiosApi.tsx';
import React from "react"; import React from "react";
import RedAlert from "../Alert/RedAlert.tsx";
const dropIn = { const dropIn = {
hidden: { hidden: {
@ -26,37 +27,58 @@ const dropIn = {
// ) // )
// } // }
const ModalEdit = ( handleClose ) => { const ModalEdit = () => {
// let new_name = ""; // let new_name = "";
const [nickname, setNickname] = useState(""); const [nickname, setNickname] = useState("");
const [errTaken, setErrTaken] = useState(false);
const handler = e => const closeTaken = () => setErrTaken(false);
{ const [errTooShort, setErrTooShort] = useState(false);
const closeTooShort = () => setErrTooShort(false);
const handler = (e: { target: { value: React.SetStateAction<string>; }; }) => {
setNickname(e.target.value); setNickname(e.target.value);
console.log("testeeeee") console.log("testeeeee")
const postNickname = async ()=>{ const postNickname = async () => {
try{ // try{
await api.post("/nickname", {nickname: nickname}) // await api.post("/nickname", {nickname: nickname})
// setUser(tmpUser.data); // // setUser(tmpUser.data);
// setIsLoading(false) // // setIsLoading(false)
} // }
catch(err){ // catch(err){
console.log(err); // console.log(err);
} // }
}; };
postNickname(); postNickname();
} }
const handlePostNickname = async () => const handlePostNickname = async () => {
{ console.log("nickname=", nickname)
console.log("nickname=" ,nickname) try {
try{ // console.log("cest ici = ",ret);
await api.post("/nickname", {nickname: nickname}) // if (!ret)
window.location.reload(); // console.log("test ret =", ret.data);
if (nickname.length > 3) {
const ret = await api.post("/nickname", { nickname: nickname });
if (ret.data) {
console.log("ici error = ", ret.data);
window.location.reload();
}
else {
console.log("nickname already set = ", ret.data);
setErrTaken(true);
}
}
else if (nickname.length < 3)
{
setErrTooShort(true);
}
// setUser(tmpUser.data); // setUser(tmpUser.data);
// setIsLoading(false) // setIsLoading(false)
} }
catch(err){ catch (err) {
console.log(err); console.log(err);
} }
} }
@ -66,23 +88,34 @@ const ModalEdit = ( handleClose ) => {
// //do nothing // //do nothing
// } // }
return ( return (
<motion.div <motion.div
className="modal" className="modal"
variants={dropIn} variants={dropIn}
initial="hidden" initial="hidden"
animate="visible" animate="visible"
exit="exit"> exit="exit">
<h2>Type your new name</h2> <h1>Type your new name</h1>
<input className="text" maxLength="10" type="text" value={nickname} onChange={handler} handleClose/> <input className="text" minLength={2} maxLength={10} type="text" value={nickname} onChange={handler} />
<div> <div>
<div className="button" onClick={ () => handlePostNickname()}> <div className="button" onClick={handlePostNickname}>
change change
{/* <Link className="button" to={""}>change</Link> */} {/* <Link className="button" to={""}>change</Link> */}
</div>
</div> </div>
</motion.div> <AnimatePresence initial={false} onExitComplete={() => null}>
{
errTaken ? (
<RedAlert handleClose={closeTaken} text="Error: Nickname already taken" />
) : ("")
}
{
errTooShort ? (
<RedAlert handleClose={closeTooShort} text="Error: Nickname it too short" />
) : ("")
}
</AnimatePresence>
</div>
</motion.div>
) )
} }

View File

@ -1,14 +1,25 @@
import React from "react"; import React from "react";
import api from "../../script/axiosApi"
function Logout(){ function Logout(){
const logout = async () =>{
try {
await api.post("/logout")
} catch (err) {
console.log(err);
}
}
logout();
localStorage.clear(); localStorage.clear();
const path = 'http://' + process.env.REACT_APP_BASE_URL + '/'; const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
// 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({}, '', path);
window.location.reload(); window.location.reload();
return (<></>) return (<></>)

View File

@ -62,8 +62,20 @@ function WinLoss() {
const getUser = async ()=>{ const getUser = async ()=>{
try{ try{
// const tmpUser = await api.get("/profile") // const tmpUser = await api.get("/profile")
const tmpUser = await api.post("/user", {username: username}) console.log("username win loss=", username)
const tmpHistory = await api.post("/history", {username: username}) let tmpUser;
let tmpHistory;
if (username)
{
tmpUser = await api.post("/user", {username: username});
tmpHistory = await api.post("/history", {username: username})
}
else
{
tmpUser = await api.get("/profile");
tmpHistory = await api.post("/history", {username: tmpUser.data.username})
}
setHistory(tmpHistory.data); setHistory(tmpHistory.data);
setUser(tmpUser.data); setUser(tmpUser.data);
setIsLoading(false) setIsLoading(false)
@ -83,7 +95,7 @@ function WinLoss() {
// {isLoading ? ( // {isLoading ? (
// <h1>Loading...</h1> // <h1>Loading...</h1>
// ) : ( // ) : (
// <h1>{user.username}</h1> // <h1>{user.username}</h1>
// )} // )}
// </div> // </div>
@ -94,7 +106,7 @@ function WinLoss() {
// <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 {user.win}/{user.loss}</h2>
{history.map((c: Matchlog, index) => { {history.map((c: Matchlog, index) => {
return ( return (
<div key={index} className='elements'> <div key={index} className='elements'>

View File

@ -26,7 +26,7 @@ export const SidebarData = [
cName: 'nav-text' cName: 'nav-text'
}, },
{ {
title: 'Friend', title: 'Friends',
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/23 17:12:07 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -27,6 +27,7 @@ const UserChat = styled.div `
gap: 5px; gap: 5px;
color: white; color: white;
cursor: pointer; cursor: pointer;
margin-top: 15px;
&:hover{ &:hover{
background-color: #3e3c61; background-color: #3e3c61;
@ -46,7 +47,7 @@ interface UserProps {
export default function Friend({currentUser}: UserProps) export default function Friend({currentUser}: UserProps)
{ {
const [profilePicture, setProfilePicture] = useState(''); const [profilePicture, setProfilePicture] = useState('');
useEffect(() => { useEffect(() => {
const fetchProfilePicture = async () => { const fetchProfilePicture = async () => {
try { try {
@ -59,21 +60,22 @@ export default function Friend({currentUser}: UserProps)
console.error('Error fetching profile picture:', error); console.error('Error fetching profile picture:', error);
} }
}; };
fetchProfilePicture(); fetchProfilePicture();
}) }, []);
function getStatus(friend: User) function getStatus(friend: User)
{ {
let status = friend.status let status = friend.status
let session =friend.sessionNumber
console.log(`session= ${session}`)
console.log(`status= ${status}`) console.log(`status= ${status}`)
let statusColor; let statusColor;
if (status === 0) if (status === 0)
statusColor = 'grey'; statusColor = 'grey';
else if (status === 1) else if (status === 1)
statusColor = 'green'; statusColor = 'green';
else if (status === 2) else if (status === 2)
statusColor = 'blue'; statusColor = 'blue';
return statusColor; return statusColor;
} }
@ -94,24 +96,24 @@ export default function Friend({currentUser}: UserProps)
}; };
return ( return (
<UserChat> <UserChat className="centermargin">
{profilePicture ? ( {profilePicture ? (
<img className="pic-user" src={`data:image/jpeg;base64,${profilePicture}`} /> <img className="pic-user" src={`data:image/jpeg;base64,${profilePicture}`} />
) : ( ) : (
<img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" /> <img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" />
)} )}
<div className="infoSideBar"> <div className="end">
<span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span> <span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span>
<RxCircle color={getStatus(currentUser)} /> <div className="end">
<button onClick={() => handleSpectate(currentUser)} >Invite</button> <RxCircle className="friendRequest" color={getStatus(currentUser)} />
{getStatus(currentUser) !== 'blue' ? ( </div>
<></> </div>
) : (
<button onClick={() => handleSpectate(currentUser)} >Spectate</button>
)}
</div>
</UserChat> </UserChat>
) )
} }
// spectate visible
// {getStatus(currentUser) !== 'blue' ? (
// <></>
// ) : (
// <button className="friendRequest" onClick={() => handleSpectate(currentUser)} >Spectate</button>
// )}

View File

@ -15,7 +15,7 @@ const UserChat = styled.div `
gap: 5px; gap: 5px;
color: white; color: white;
cursor: pointer; cursor: pointer;
margin-top: 10px;
&:hover{ &:hover{
background-color: #3e3c61; background-color: #3e3c61;
} }
@ -37,7 +37,7 @@ export default function Friend({currentUser}: UserProps)
const [request, setRequest] = useState<User>(); //user who invite const [request, setRequest] = useState<User>(); //user who invite
const [clickEvent, setClickEvent] = useState(false); const [clickEvent, setClickEvent] = useState(false);
// const [user, setUser] = useState(null); // const [user, setUser] = useState(null);
useEffect(() => { useEffect(() => {
const fetchProfilePicture = async () => { const fetchProfilePicture = async () => {
try { try {
@ -54,12 +54,12 @@ export default function Friend({currentUser}: UserProps)
console.error('Error fetching profile picture:', error); console.error('Error fetching profile picture:', error);
} }
}; };
fetchProfilePicture(); fetchProfilePicture();
}, [clickEvent]) }, [clickEvent])
const handleButtonClick = (user: User) => { const handleButtonClick = (user: 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({}, '', path);
@ -94,20 +94,21 @@ export default function Friend({currentUser}: UserProps)
} }
return ( return (
<UserChat> <UserChat className="centermargin">
{profilePicture ? ( {profilePicture ? (
<img className="pic-user" src={`data:image/jpeg;base64,${profilePicture}`} /> <img className="pic-user" src={`data:image/jpeg;base64,${profilePicture}`} />
) : ( ) : (
<img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" /> <img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" />
)} )}
{request ? ( {request ? (
<div className="infoSideBar"> <div className="end">
<span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span> <span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span>
<RxCheckCircled onClick={() => Accept(request)} color={'green'}/> <div className="end">
<RxCircleBackslash onClick={() => Refuse(request)} color={'red'}/> <RxCheckCircled className="friendRequest" onClick={() => Accept(request)} color={'green'}/>
<RxCircleBackslash className="friendRequest" onClick={() => Refuse(request)} color={'red'}/>
</div>
</div> </div>
) : ( "" )} ) : ( "" )}
</UserChat> </UserChat>
) )
} }

View File

@ -7,6 +7,7 @@ import styled from "styled-components";
import Friend from './Friend.tsx'; import Friend from './Friend.tsx';
import FriendRequest from './FriendRequest.tsx'; import FriendRequest from './FriendRequest.tsx';
import {IoMdPeople} from 'react-icons/io'
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 {User} from "../../../interfaces.tsx"
@ -25,7 +26,7 @@ const TouchDiv = styled.div`
margin-top: 21px; margin-top: 21px;
cursor: pointer; cursor: pointer;
justify-content: space-around; justify-content: space-around;
&:hover { &:hover {
color: #F4F3EF; color: #F4F3EF;
} }
@ -42,7 +43,7 @@ function Social (){
useEffect(()=> { useEffect(()=> {
const getFriend = async ()=>{ const getFriend = async ()=>{
try{ try{
const tmpFriends = await api.get("/friends") const tmpFriends = await api.get("/friends")
const tmpUser = await api.get("/profile") const tmpUser = await api.get("/profile")
const tmpInv = await api.get("/inviteRequest") const tmpInv = await api.get("/inviteRequest")
const pic = await api.post("/getPicture", {username: tmpUser.data.username}) const pic = await api.post("/getPicture", {username: tmpUser.data.username})
@ -86,28 +87,17 @@ function Social (){
return ( return (
<div> <div>
<div className='navbar'> <div className='navbarSocial'>
{/* <img src={DefaultPic} alt="profile" className="pic"/> */} {/* <img src={DefaultPic} alt="profile" className="pic"/> */}
{profilePicture ? ( <IoMdPeople className="catchat"/>
<img className="pic" src={`data:image/jpeg;base64,${profilePicture}`} />
) : (
<img className="pic" src={DefaultPicture} alt="Default Profile Picture" />
)}
<span> <span>
{isLoading || !user ? ( {isLoading || !user ? (
<h4>Loading...</h4> <h4>Loading...</h4>
) : ( ) : (
<h4>{user.nickname}</h4> <h2>Friends</h2>
)} )}
</span> </span>
<div className="end">
<TouchDiv>
<MdOutlineGroupAdd/>
</TouchDiv>
<TouchDiv>
<ImBlocked/>
</TouchDiv>
</div>
</div> </div>
{/* map with fiend request */} {/* map with fiend request */}
@ -119,8 +109,9 @@ function Social (){
{friends.map(c=> ( {friends.map(c=> (
<Friend currentUser={c}/> <Friend currentUser={c}/>
))} ))}
</div> </div>
) )
} }
export default Social export default Social

View File

@ -1,27 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import reportWebVitals from './reportWebVitals';
import Header from './components/Header.tsx';
import Head from './pages/Head.tsx';
import App from './components/App.tsx';
import './styles/index.css';
import './styles/App.css'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<div className="App">
<Head />
<BrowserRouter>
<Header />
<App/>
</BrowserRouter>
</div>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

View File

@ -0,0 +1,22 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import Header from './components/Header';
import Head from './pages/Head';
import App from './components/App';
import './styles/index.css';
import './styles/App.css';
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
<div className="App">
<Head />
<BrowserRouter>
<Header />
<App/>
</BrowserRouter>
</div>
);

View File

@ -1,112 +1,18 @@
import React, { useCallback, useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import api from '../script/axiosApi.tsx'; import api from '../script/axiosApi.tsx';
// function DoubleAuth() {
// // const enabled = await api.get("/2fa");
// // const response = await api.get("/2fa");
// // const enabled = response.data;
// // console.log(`enable= ${enabled.data}`)
// // const enabled = 0;
// let enabled;
// useEffect(() => {
// async function get2fa()
// {
// const response = await api.get("/2fa");
// const enabled = response.data;
// console.log(`enable= ${enabled.data}`)
// }
// // const enabled = 0;
// }, [])
// useEffect(() => {
// async function get2fa()
// {
// api.get('/api/QRcode', { responseType: 'blob' })
// .then(response => {
// const reader = new FileReader();
// reader.onloadend = () => {
// setImageSrc(reader.result);
// };
// reader.readAsDataURL(response.data);
// })
// .catch(error => {
// console.error(error);
// });
// } }, []);
// // const [verificationCode, setVerificationCode] = useState('');
// // const [invalidCode, setInvalidCode] = useState(false);
// const handleSubmit = () => {
// // async (e) => {
// // e.preventDefault();
// // const result = await verifyOtp(verificationCode);
// // if (result) return (window.location = '/');
// // setInvalidCode(true);
// // },
// // [verificationCode]
// };
// let sourceCode
// if (!enabled)
// {
// api.get('/QRcode')
// .then(response => {
// sourceCode = response.data;
// console.log(sourceCode);
// })
// .catch(error => {
// console.error(error);
// });
// }
// return (
// <div>
// {!enabled && (
// <div>
// <p>Scan the QR code on your authenticator app</p>
// <img src={sourceCode} />
// </div>
// )}
// <form onSubmit={handleSubmit}>
// {/* <Input
// id="verificationCode"
// label="Verification code"
// type="text"
// value={verificationCode}
// onChange={(e) => setVerificationCode(e.target.value)}
// /> */}
// <button type="submit">Confirm</button>
// {/* {invalidCode && <p>Invalid verification code</p>} */}
// </form>
// </div>
// );
// }
// import { toFileStream } from 'qrcode';
const DoubleAuth = () => { const DoubleAuth = () => {
const [imageSrc, setImageSrc] = useState(''); // const [imageSrc, setImageSrc] = useState('');
const [imageSrc, setImageSrc] = useState<string | ArrayBuffer | null>('');
useEffect(() => { useEffect(() => {
async function getCode(){ async function getCode(){
await api.get('/QRcode', { responseType: 'blob' }) await api.get('/QRcode', { responseType: 'blob' })
.then(response => { .then(response => {
const reader = new FileReader(); const reader = new FileReader();
if (!reader)
return ;
reader.onloadend = () => { reader.onloadend = () => {
setImageSrc(reader.result); setImageSrc(reader.result);
}; };
@ -119,23 +25,12 @@ const DoubleAuth = () => {
getCode(); getCode();
}, []); }, []);
// return (
// <div>
// {imageSrc && <img src={imageSrc} alt="QR Code" />}
// </div>
// );
// <img src={sourceCode} />
return ( return (
<div> <div>
<div> <div>
<p>Scan the QR code on your authenticator app</p> <p>Scan the QR code on your authenticator app</p>
{imageSrc && <img src={imageSrc} alt="QR Code" />} {imageSrc && <img src={imageSrc.toString()} alt="QR Code" />}
</div> </div>
{/* <form onSubmit={handleSubmit}>
<button type="submit">Confirm</button>
</form> */}
</div> </div>
); );

View File

@ -1,13 +1,9 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
// import { useState, useRef } from 'react';
import DrawCanvas from './canvas.tsx'; import DrawCanvas from './canvas.tsx';
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 React from 'react'; import React from 'react';
// import { withRouter } from 'react-router-dom';
interface GameProps { interface GameProps {
privateParty: boolean, privateParty: boolean,
@ -18,7 +14,6 @@ interface GameProps {
function Field() function Field()
{ {
useEffect(() => { useEffect(() => {
// const location = useLocation();
const queryParams = queryString.parse(window.location.search); const queryParams = queryString.parse(window.location.search);
console.log("launch canva hehe") console.log("launch canva hehe")
@ -56,7 +51,6 @@ function Field()
return () => { return () => {
console.log("Cleanup"); console.log("Cleanup");
// cleanup(); // Call the cleanup function to stop the ongoing process or perform necessary cleanup tasks
if (cleanup) if (cleanup)
cleanup(); cleanup();
}; };

View File

@ -7,9 +7,7 @@ function Head()
<meta charSet="utf-8"></meta> <meta charSet="utf-8"></meta>
<link href="./css/header.css" rel="stylesheet"></link> <link href="./css/header.css" rel="stylesheet"></link>
<title>BEST PONG EVER</title> <title>BEST PONG EVER</title>
{/* <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 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,50 +0,0 @@
import '../styles/old.css';
import '../styles/field.css';
import { useLocation } from 'react-router-dom';
import api from '../script/axiosApi.tsx';
function HomeLogin()
{
const login2 = () => {
console.log('Hello from myFunction');
api.get('/profile').then((response) => {
const data = response;
const myJSON = JSON.stringify(response.data);
console.log(`data response= ${myJSON}`)
});
}
const location = useLocation();
const handleButtonClick = () => {
const token = localStorage.getItem('token')
console.log(`token type= ${typeof token}`);
if (token !== null && typeof token === 'string')
{
console.log(`already token= ${localStorage.getItem('token')}`)
return ;
}
// else
// let path = "https://api.intra.42.fr/oauth/authorize?client_id=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41&redirect_uri=http%3A%2F%2F" + process.env.REACT_APP_BASE_URL + "%3A80%2Fapi%2Fauth%2Flogin&response_type=code";
let path = "https://api.intra.42.fr/oauth/authorize?client_id=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41&redirect_uri=http%3A%2F%2F" + process.env.REACT_APP_BASE_URL + "%2Fapi%2Fauth%2Flogin&response_type=code"
window.location.replace(path);
};
return (
<div className="notClicked">
<button onClick={handleButtonClick} className="playButton" >LOGIN</button>
{/* <div className ="loginForm">
<button className="submit" onClick={login2}>test button</button>
</div> */}
{/* <div className ="loginForm">
<button className="submit" onClick={() => api.post('/win')}>add win</button>
</div>
<div className ="loginForm">
<button className="submit" onClick={() => api.post('/loss')}>add loss</button>
</div> */}
</div>
);
}
export default HomeLogin;

View File

@ -6,65 +6,40 @@
/* 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/26 07:06:35 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
// import { React, useState } from "react";
import '../styles/Profile.css' import '../styles/Profile.css'
// import '../styles/App.css' import RedAlert from "../components/Alert/RedAlert.tsx";
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.tsx";
import { motion, AnimatePresence } from 'framer-motion' import { motion, AnimatePresence } from 'framer-motion'
// import { AiFillEdit } from 'react-icons/ai'
// 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.tsx";
import {AiOutlineHistory} from 'react-icons/ai' import {AiOutlineCloseCircle, AiOutlineHistory} from 'react-icons/ai'
import { MdQrCodeScanner, MdOutlinePhotoLibrary } from 'react-icons/md'; import { MdQrCodeScanner, MdOutlinePhotoLibrary } from 'react-icons/md';
import { GiWingedSword, GiCrownedSkull } from 'react-icons/gi'; import { GiWingedSword, GiCrownedSkull } from 'react-icons/gi';
// import { Link } from "react-router-dom";
// import {UserProfile} from "../DataBase/DataUserProfile";
// import axios from "axios";
import api from '../script/axiosApi.tsx'; import api from '../script/axiosApi.tsx';
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 React, { useState, useEffect } from "react";
// import * as React from 'react';
// import { useState, useEffect, useParams} from "react";
import React, { useState, useEffect, useRef, ChangeEventHandler } from "react";
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import {User, Conv} from "../../interfaces.tsx" import {User} from "../../interfaces.tsx"
import YellowAlert from '../components/Alert/YellowAlert.tsx'; import YellowAlert from '../components/Alert/YellowAlert.tsx';
// axios.get("http://localhost/api")
// .then((response) => {
// response = response.json()
// response.then((result) => {
// console.log(result)
// console.log("ceci est un test")
// })
// })
function Profile () { function Profile () {
const [user, setUser] = useState<User>(); const [user, setUser] = useState<User>();
const [isLoading, setIsLoading] = useState<boolean>(true); const [isLoading, setIsLoading] = useState<boolean>(true);
const [modalOpen, setModalOpen] = useState<boolean>(false); const [modalOpen, setModalOpen] = useState<boolean>(false);
const [mine, setMine] = useState<boolean>(false); const [mine, setMine] = useState<boolean>(false);
const [error, setError] = useState<boolean>(false);
const close = () => setModalOpen(false); const close = () => setModalOpen(false);
const closeError = () => setError(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 [profilePicture, setProfilePicture] = useState(''); const [profilePicture, setProfilePicture] = useState('');
const handleFileChange = async (event: { target: { files: any; }; }) => { const handleFileChange = async (event: { target: { files: any; }; }) => {
// const files = event.target.files;
// if (files && files.length > 0) {
const photo = (event.target.files[0]); const photo = (event.target.files[0]);
console.log("file selected") console.log("file selected")
if (photo) { if (photo) {
@ -76,49 +51,18 @@ function Profile () {
console.log('File uploaded successfully'); console.log('File uploaded successfully');
window.location.reload(); window.location.reload();
} catch (error) { } catch (error) {
setError(true);
console.error('Error uploading file:', error); console.error('Error uploading file:', error);
} }
} }
// }
}; };
// const handleUpload = async () => {
// 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);
// }
// };
// 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 ()=>{
console.log(`username= ${username}`) console.log(`username= ${username}`)
// const pic let pic;
let pic
try{ try{
console.log("before request")
const me = await api.get("/profile") const me = await api.get("/profile")
if (!username) if (!username)
{ {
@ -126,7 +70,6 @@ function Profile () {
setUser(me.data); setUser(me.data);
console.log(`mine= true = ${mine}`) console.log(`mine= true = ${mine}`)
pic = await api.post("/getPicture", {username: me.data.username}) //good one? pic = await api.post("/getPicture", {username: me.data.username}) //good one?
// username = me.data.username
} }
else else
{ {
@ -135,9 +78,7 @@ function Profile () {
pic = await api.post("/getPicture", {username: username}) //good one? pic = await api.post("/getPicture", {username: username}) //good one?
} }
// const pic = await api.get("/picture")//pic du user
setProfilePicture(pic.data); setProfilePicture(pic.data);
// console.log(`user= ${tmpUser.data.username}`)
setIsLoading(false) setIsLoading(false)
} }
catch(err){ catch(err){
@ -149,8 +90,6 @@ function Profile () {
return ( return (
<div className="profile"> <div className="profile">
{/* <img className="profile-pic" src={DefaultPicture} alt="Profile pic" />
*/}
{profilePicture ? ( {profilePicture ? (
<img className="profile-pic" src={`data:image/jpeg;base64,${profilePicture}`} /> <img className="profile-pic" src={`data:image/jpeg;base64,${profilePicture}`} />
) : ( ) : (
@ -160,12 +99,9 @@ function Profile () {
{isLoading || !user ? ( {isLoading || !user ? (
<h1>Loading...</h1> <h1>Loading...</h1>
) : ( ) : (
<h1>{user.nickname}</h1> <h1 className='user_name'>{user.nickname}</h1>
)} )}
</span> </span>
{mine ? ( {mine ? (
<div> <div>
<motion.div > <motion.div >
@ -176,25 +112,22 @@ function Profile () {
<> <>
<label htmlFor="file-input" className="edit_name"><MdOutlinePhotoLibrary/></label> <label htmlFor="file-input" className="edit_name"><MdOutlinePhotoLibrary/></label>
<input type="file" id="file-input" className="file-input" accept="image/*" onChange={handleFileChange} /> <input type="file" id="file-input" className="file-input" accept="image/*" onChange={handleFileChange} />
<AnimatePresence initial={false} onExitComplete={() => null}>
{error ? (
<RedAlert handleClose={closeError} text={'Error : upload failed'} />
): ("")}
</AnimatePresence>
</> </>
)} )}
</motion.div> </motion.div>
{/* <div className="file-upload-container"> */}
{/* <button onClick={handleUpload} className="upload-button">Upload</button> */}
{/* <button onClick={handleUpload} className="upload-button">Upload</button> */}
{/* </div> */}
</div> </div>
) : ( ) : (
<></> <></>
)} )}
<AnimatePresence <AnimatePresence
initial={false} initial={false}
onExitComplete={() => null}> onExitComplete={() => null}>
{modalOpen && <ModalEdit modalOpen={modalOpen} handleclose={close}/>} {modalOpen && <ModalEdit/>}
</AnimatePresence> </AnimatePresence>
</div> </div>
) )
@ -202,8 +135,7 @@ function Profile () {
function Home () { function Home () {
const [move, setmove ] = useState(false); const [move, setmove ] = useState(false);
const [user, setUser] = useState([]); const [user, setUser] = useState<User>();
const [successQr, setSuccessQr] = useState(false); const [successQr, setSuccessQr] = useState(false);
const [successSword, setSuccessSword] = useState(false); const [successSword, setSuccessSword] = useState(false);
const [successCrown, setSuccessCrown] = useState(false); const [successCrown, setSuccessCrown] = useState(false);
@ -211,12 +143,21 @@ function Home () {
const closeSword = () => setSuccessSword(false); const closeSword = () => setSuccessSword(false);
const closeCrown = () => setSuccessCrown(false); const closeCrown = () => setSuccessCrown(false);
const { username } = useParams();
useEffect(() => { useEffect(() => {
const fetchSuccess = async () => { const fetchSuccess = async () => {
try { try {
const tmpUser = await api.get("/profile"); if (!username)
setUser(tmpUser.data); {
const tmpUser = await api.get("/profile");
setUser(tmpUser.data);
}
else
{
const tmpUser = await api.post("/user", {username: username});
setUser(tmpUser.data);
}
} }
catch (error) catch (error)
{ {
@ -224,7 +165,7 @@ function Home () {
} }
}; };
fetchSuccess(); fetchSuccess();
}) }, []);
return ( return (
<motion.div className="page" <motion.div className="page"
@ -232,19 +173,19 @@ function Home () {
animate={{opacity: 1}} animate={{opacity: 1}}
exit={{opacity: -1}}> exit={{opacity: -1}}>
<div> <div>
{user.otp_verified ? ( {user && user.otp_verified ? (
<MdQrCodeScanner className='success' onClick={() => setSuccessQr(true)}/> <MdQrCodeScanner className='success' onClick={() => setSuccessQr(true)}/>
):("")} ):("")}
{user.win >= 2 ? ( {user && user.win >= 2 ? (
<GiWingedSword className="success" onClick={() => setSuccessSword(true)}/> <GiWingedSword className="success" onClick={() => setSuccessSword(true)}/>
):("")} ):("")}
{user && user.win >= 5 ? (
{user.win >= 5 ? (
<GiCrownedSkull className="success" onClick={() => setSuccessCrown(true)}/> <GiCrownedSkull className="success" onClick={() => setSuccessCrown(true)}/>
):("")} ):("")}
</div> </div>
<div className="home"> <div className="home">
<motion.div animate={{x: move ? -200: 120}} <motion.div
animate={{x: move ? '-50%' : '25%'}}
transition={{type: "tween", duration: 0.5}}> transition={{type: "tween", duration: 0.5}}>
<Profile/> <Profile/>
</motion.div> </motion.div>
@ -254,9 +195,8 @@ function Home () {
</div> </div>
<motion.div <motion.div
className="div_history" className="div_history"
// className="history"
onClick={ () => setmove(!move)}> onClick={ () => setmove(!move)}>
<Link to="#" className="history"><AiOutlineHistory/> Match History</Link> <Link to="#" className="history"> {move ? (<AiOutlineCloseCircle/>):(<AiOutlineHistory/>)} Match History</Link>
</motion.div> </motion.div>
<AnimatePresence initial={false} onExitComplete={() => null}> <AnimatePresence initial={false} onExitComplete={() => null}>
{successQr ? ( {successQr ? (
@ -271,8 +211,8 @@ function Home () {
<YellowAlert handleClose={closeSword} text={"Success: 2 victory ? You won the noobi warrior success!"} icon={3}/> <YellowAlert handleClose={closeSword} text={"Success: 2 victory ? You won the noobi warrior success!"} icon={3}/>
) : ("")} ) : ("")}
</AnimatePresence> </AnimatePresence>
</motion.div> </motion.div>
) )
} }
export default Home export default Home

View File

@ -1,47 +0,0 @@
// import GoogleLogin from 'react-google-login';
import { useEffect } from 'react';
import axios from 'axios';
import React from 'react';
// import setupLogin from '../script/login42';
// import React, { useEffect } from 'react';
function Login42()
{
useEffect(() => {
console.log("you said yes to connect with 42");
const url = new URL(window.location.href);
// console.log(`url is= ${url}`);
const code = url.searchParams.get('code');
console.log(`code is= ${code}`);
const data = {
grant_type: 'authorization_code',
// client_id: 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41',
// client_secret: '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',
client_id: process.env.REACT_APP_CLIENT_UID,
client_secret: process.env.REACT_APP_API_SECRET,
code: code,
redirect_uri: 'http://' + process.env.REACT_APP_BASE_URL + '/login42',
};
axios.post('https://api.intra.42.fr/oauth/token', data)
.then(response => {
// handle success response
console.log(response);
})
.catch(error => {
// handle error response
console.error(error);
});
}, []);
return (
<div>
<p>"COUCOU LOGIN" </p>
{/* <script src="../script/login42.js"></script> */}
</div>
);
}
export default Login42;

View File

@ -0,0 +1,23 @@
import '../styles/old.css';
import '../styles/field.css';
import React from 'react';
function HomeLogin()
{
const handleButtonClick = () => {
const token = localStorage.getItem('token')
console.log(`token type= ${typeof token}`);
if (token !== null && typeof token === 'string')
return ;
let path = process.env.REACT_APP_INTRA_URL || "";
window.location.replace(path);
};
return (
<div className="notClicked">
<button onClick={handleButtonClick} className="playButton" >LOGIN</button>
</div>
);
}
export default HomeLogin;

View File

@ -1,29 +1,9 @@
import React from "react"; import React from "react";
// import Sidebar from '../components/Messages/Sidebar'
import Chats from "../components/Messages/Chats.tsx" import Chats from "../components/Messages/Chats.tsx"
import '../styles/Messages.css' import '../styles/Messages.css'
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
// 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 (
<> <>
<motion.div className="home" <motion.div className="home"
@ -31,7 +11,6 @@ function Messages() {
animate={{opacity: 1}} animate={{opacity: 1}}
exit={{opacity: 0}}> exit={{opacity: 0}}>
<div className="container"> <div className="container">
{/* <Sidebar/> */}
<Chats/> <Chats/>
</div> </div>
</motion.div> </motion.div>

View File

@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import '../styles/field.css'; import '../styles/field.css';
// import { useHistory } from 'react-router-dom';
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
function PlayButton() { function PlayButton() {
@ -15,8 +14,6 @@ function PlayButton() {
return ( return (
<div className="notClicked" id="canvas_container"> <div className="notClicked" id="canvas_container">
<button onClick={handleButtonClick} className="playButton">Play</button> <button onClick={handleButtonClick} className="playButton">Play</button>
{/* !buttonClicked && <button onClick={handleButtonClick}>Draw on Canvas</button> */}
</div> </div>
); );
} }

View File

@ -6,14 +6,14 @@ import "../styles/App.css";
import api from '../script/axiosApi.tsx'; import api from '../script/axiosApi.tsx';
import QRCodeStyling from "qr-code-styling"; import QRCodeStyling from "qr-code-styling";
import { motion } from 'framer-motion' import { AnimatePresence, motion } from 'framer-motion'
import RedAlert from "../components/Alert/RedAlert.tsx";
const qrCode = new QRCodeStyling({ const qrCode = new QRCodeStyling({
width: 300, width: 300,
height: 300, height: 300,
// image: "../assets/profile.jpg",
dotsOptions: { dotsOptions: {
color: "black", color: "black",
type: "rounded" type: "rounded"
@ -28,16 +28,14 @@ const qrCode = new QRCodeStyling({
}); });
function QrCode () { function QrCode () {
// const url = "https://www.youtube.com";
// const ref = useRef(null);
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
const [user, setUser] = useState(false); const [user, setUser] = useState(false);
const [url, setUrl] = useState(""); const [url, setUrl] = useState("");
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);
const [err, setErr] = useState(false);
// const history = useHistory(); const closeErr = () => setErr(false);
useEffect(() => { useEffect(() => {
if (ref.current) if (ref.current)
@ -54,9 +52,6 @@ function QrCode () {
const otpData = await api.post("/otp"); const otpData = await api.post("/otp");
setUrl(otpData.data.otpauth_url); setUrl(otpData.data.otpauth_url);
setSecret(otpData.data.base32_secret); setSecret(otpData.data.base32_secret);
// const tmpUser = await api.get("/profile")
// console.log("test")
// console.table(convs);
} }
catch(err){ catch(err){
console.log(err); console.log(err);
@ -72,31 +67,23 @@ function QrCode () {
const handleKeyPress = async (e: { key: string; })=>{ const handleKeyPress = async (e: { key: string; })=>{
// console.log(`e in press= ${e.key}`)
if (e.key !== "Enter") if (e.key !== "Enter")
return ; return ;
try{ try{
console.log("code= ", code)
const res = await api.post("/verifyOtp", {token: code}) const res = await api.post("/verifyOtp", {token: code})
console.log("res= ", res.data) if (!res.data)
console.log("res= ", res) {
setErr(true);
}
if (res.data === 1) if (res.data === 1)
{ {
console.log("registered") const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
// history.push('/login')
const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
window.history.pushState({}, '', path); window.history.pushState({}, '', path);
window.location.reload(); window.location.reload();
} }
else else
{
console.log("bad code") console.log("bad code")
//alert ?? retry }
}
// redirect('/test')
}
catch(err){ catch(err){
console.log(err) console.log(err)
} }
@ -105,8 +92,6 @@ function QrCode () {
const handleDesactivate = async () => { const handleDesactivate = async () => {
try { try {
await api.post("/deleteOtp") await api.post("/deleteOtp")
// const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
// window.history.pushState({}, '', path);
window.location.reload(); window.location.reload();
} catch(err) { } catch(err) {
console.log(err); console.log(err);
@ -114,18 +99,6 @@ function QrCode () {
}; };
return ( return (
// <motion.div className="page"
// initial={{opacity: -1}}
// animate={{opacity: 1}}
// exit={{opacity: -1}}>
// <h1>QRcode</h1>
// <h3>{secret}</h3>
// <div ref={ref} />
// <input type="text" className="qr" placeholder="Type The Code"/>
// {}
// </motion.div>
<motion.div <motion.div
className="page" className="page"
initial={{ opacity: -1 }} initial={{ opacity: -1 }}
@ -138,7 +111,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> */}
</> </>
)} )}
@ -148,7 +120,7 @@ function QrCode () {
<h1>Double Auth Validation</h1> <h1>Double Auth Validation</h1>
<input <input
onKeyDown={handleKeyPress} onKeyDown={handleKeyPress}
type="text" type="number"
className="qr" className="qr"
placeholder="6 Digits Code" placeholder="6 Digits Code"
value={code} value={code}
@ -156,27 +128,16 @@ function QrCode () {
/> />
</> </>
) : ( ) : (
<button onClick={handleDesactivate}>Desactivate 2FA</button> <button className="desactivate" onClick={handleDesactivate}>Desactivate 2FA</button>
)} )}
<AnimatePresence
initial={false}
onExitComplete={() => null}>
{err ? (<RedAlert handleClose={closeErr} text="Error: Bad intput. Try again"/>):("")}
</AnimatePresence>
</> </>
{/* {!localStorage.getItem('token') && (
<>
<h1>Double Auth</h1>
<input onKeyDown={handleKeyPress}
type="text"
className="qr"
placeholder="6 Digits Code"
onChange={(e) => setCode(e.target.value)}
/>
</>
) : (<button onClick={ handleDesactivate }>Desactivate 2FA</button>)}
*/}
{/* {!activated && (
<button onClick={() => setActivated(true)}>Activate</button>
)} */}
</motion.div> </motion.div>
) )
} }
export default QrCode export default QrCode

View File

@ -1,9 +0,0 @@
import React from "react";
function Social (){
return (
<div>je suis la partie social</div>
)
}
export default Social

View File

@ -1,12 +1,6 @@
// import io from 'socket.io-client'; import { useEffect } from 'react';
import api from '../script/axiosApi.tsx'; import api from '../script/axiosApi.tsx';
// import { useEffect, useRef } from 'react';
import io from 'socket.io-client'; import io from 'socket.io-client';
// const socket = io('http://192.168.1.14:4000');
// const socket = io('http://86.209.110.20:4000');
// const socket = io('http://172.29.113.91:4000');
interface GameProps { interface GameProps {
privateParty: boolean, privateParty: boolean,
@ -16,6 +10,22 @@ interface GameProps {
function DrawCanvas(option: number, gameParam: GameProps) { function DrawCanvas(option: number, gameParam: GameProps) {
useEffect(() => {
const handleBeforeUnload = async (event: { preventDefault: () => void; returnValue: string; }) => {
try {
await api.post("/status", {status: 1});
} catch (err) {
console.log(err);
}
};
window.addEventListener('beforeunload', handleBeforeUnload);
return () => {
window.removeEventListener('beforeunload', handleBeforeUnload);
};
}, []);
console.log(`option= ${option}`); console.log(`option= ${option}`);
const superpowerModifier = option & 1; // Retrieves the superpower modifier const superpowerModifier = option & 1; // Retrieves the superpower modifier
const obstacleModifier = (option >> 1) & 1; // Retrieves the obstacle modifier const obstacleModifier = (option >> 1) & 1; // Retrieves the obstacle modifier
@ -25,11 +35,6 @@ function DrawCanvas(option: number, gameParam: GameProps) {
console.log(`obstacleModifier = ${obstacleModifier}`); console.log(`obstacleModifier = ${obstacleModifier}`);
console.log(`speedModifier = ${speedModifier}`); console.log(`speedModifier = ${speedModifier}`);
// const socketRef = useRef(null);
// socketRef.current = io('http://localhost:4000');
function launchGame() function launchGame()
{ {
if (!gameParam.privateParty) if (!gameParam.privateParty)
@ -49,11 +54,8 @@ function DrawCanvas(option: number, gameParam: GameProps) {
} }
} }
// const socket = socketRef.current
console.log("start function"); console.log("start function");
const canvas = document.getElementById('myCanvas') as HTMLCanvasElement | null;
// let canvas: HTMLElement | null;
const canvas = document.getElementById('myCanvas') as HTMLCanvasElement | null;;
if (!canvas) if (!canvas)
return ; return ;
@ -61,15 +63,7 @@ function DrawCanvas(option: number, gameParam: GameProps) {
if(!ctx) if(!ctx)
return ; return ;
const socket = io('http://localhost:4000', { transports: ['polling'] }); const socket = io('http://' + process.env.REACT_APP_SOCKET_URL + ':4000', { transports: ['polling'] });
// useEffect(() => {
// console.log("useeffect?????????????????")
// return () => {
// console.log("000000000000000000000000000000000")
// socketRef.current.disconnect();
// };
// }, []);
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
@ -87,7 +81,6 @@ function DrawCanvas(option: number, gameParam: GameProps) {
let running = true; let running = true;
const scale = window.devicePixelRatio; const scale = window.devicePixelRatio;
canvas.width = canvas.offsetWidth; canvas.width = canvas.offsetWidth;
// canvas.height = canvas.width * 0.7
canvas.height = canvas.offsetHeight; canvas.height = canvas.offsetHeight;
//paddle var //paddle var
@ -124,6 +117,8 @@ function DrawCanvas(option: number, gameParam: GameProps) {
const maxScore = 5; const maxScore = 5;
let lastUpdateTime = performance.now(); let lastUpdateTime = performance.now();
let lastPower = 0;
const maxAngle = 50; const maxAngle = 50;
let maxBounceAngle = (maxAngle * Math.PI) / 180; let maxBounceAngle = (maxAngle * Math.PI) / 180;
@ -137,25 +132,13 @@ function DrawCanvas(option: number, gameParam: GameProps) {
socket.on('pong:win', async () => { socket.on('pong:win', async () => {
myScore = maxScore; myScore = maxScore;
console.log("instant win opponent disconnect") console.log("instant win opponent disconnect")
// const data = {
// myScore: myScore,
// opScore: hisScore,
// opName: opName,
// opRank: opRank,
// };
// await api.post('/win', data);
console.log("after request1") console.log("after request1")
await api.post('/status', {status: 1}); await api.post('/status', {status: 1});
console.log("after request2") console.log("after request2")
//disconnect ?
running = false; running = false;
socket.emit('pong:disconnect', {id: myId}); socket.emit('pong:disconnect', {id: myId});
console.log("before reload") console.log("before reload")
// window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong");
// window.location.reload();
return ; return ;
// console.log("send all ?? win");
}); });
@ -170,7 +153,9 @@ socket.on('pong:privateId', async (data) => {
socket.on('pong:gameId', async (data) => { socket.on('pong:gameId', async (data) => {
console.log("gameId received"); console.log("gameId received");
gameId = data; gameId = data.gameId;
console.log("gameid = ", gameId);
console.log("data gameid = ", data);
try { try {
let response = await api.get('/profile'); let response = await api.get('/profile');
@ -180,7 +165,7 @@ socket.on('pong:gameId', async (data) => {
opRank = response.data opRank = response.data
console.log(`rank= ${opRank}`); console.log(`rank= ${opRank}`);
console.log(`myname= ${myName}`); console.log(`myname= ${myName}`);
const info = { const info = {
id: myId, id: myId,
name: myName, name: myName,
@ -190,15 +175,24 @@ socket.on('pong:gameId', async (data) => {
console.log("emit to name"); console.log("emit to name");
socket.emit('pong:name', info); socket.emit('pong:name', info);
if (data.id === myId)
{
console.log("myId= true")
vX = 0.0005;
}
else
{
console.log("myId= false")
vX = -0.0005;
}
} catch (error) { } catch (error) {
console.log(error); console.log(error);
// Handle error here
return; return;
} }
}); });
socket.on('pong:name', (data) => { socket.on('pong:name', (data) => {
opName = data; opName = data.name;
console.log(`opponent Name= ${opName}`) console.log(`opponent Name= ${opName}`)
}); });
@ -222,7 +216,6 @@ socket.on('pong:info', (data) => {
vY = data.vY; vY = data.vY;
}); });
socket.on('pong:paddle', (data) => { socket.on('pong:paddle', (data) => {
console.log("paddle info receive") console.log("paddle info receive")
oPaddleY = (data.paddleY / data.height) * canvas.height oPaddleY = (data.paddleY / data.height) * canvas.height
@ -235,23 +228,25 @@ socket.on('pong:power', (data) => {
opPaddleHeight = canvas.height; opPaddleHeight = canvas.height;
setTimeout(() => { setTimeout(() => {
// code à exécuter après 5 secondes
opPaddleHeight = canvas.height * 0.25; opPaddleHeight = canvas.height * 0.25;
oPaddleY = canvas.height / 2 - paddleHeight / 2; oPaddleY = canvas.height / 2 - paddleHeight / 2;
console.log('Cinq secondes se sont écoulées.'); console.log('Cinq secondes se sont écoulées.');
}, 5000); }, 5000);
// oPaddleY = (data.paddleY / data.height) * canvas.height
}); });
socket.on('pong:point', (data) => { socket.on('pong:point', (data) => {
// hisScore += 1;
console.log("gain point"); console.log("gain point");
// if (vX != 0)
// {
// console.log("up point");
myScore = data.point; myScore = data.point;
// } vX = -0.0005;
vX = 0; vY = 0;
ballX = canvas.width / 2;
ballY = canvas.height / 2;
});
socket.on('pong:hisPoint', (data) => {
console.log("myPointawdawdawdawd point");
hisScore = data.point;
vX = -0.0005;
vY = 0; vY = 0;
ballX = canvas.width / 2; ballX = canvas.width / 2;
ballY = canvas.height / 2; ballY = canvas.height / 2;
@ -323,6 +318,25 @@ socket.on('pong:point', (data) => {
point: hisScore, point: hisScore,
} }
socket.emit('pong:point', info); socket.emit('pong:point', info);
vX = 0.0005;
}
function send_my_point()
{
if (!gameId || !canvas)
return ;
const info = {
id: myId,
gameId: gameId,
point: myScore,
}
socket.emit('pong:myPoint', info);
myScore++;
vX = 0.0005;
vY = 0;
ballX = canvas.width / 2;
ballY = canvas.height / 2;
send_forced_info();
} }
function send_paddle_info() function send_paddle_info()
@ -332,7 +346,6 @@ socket.on('pong:point', (data) => {
const info = { const info = {
id: myId, id: myId,
paddleY: paddleY, paddleY: paddleY,
// width: canvas.width,
height: canvas.height, height: canvas.height,
gameId: gameId, gameId: gameId,
}; };
@ -385,7 +398,6 @@ socket.on('pong:point', (data) => {
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);
ctx.beginPath(); ctx.beginPath();
// ctx.lineWidth = 5;
ctx.arc(canvas.width / 2, canvas.height / 2, circleRadius, 0, 2 * Math.PI); ctx.arc(canvas.width / 2, canvas.height / 2, circleRadius, 0, 2 * Math.PI);
ctx.strokeStyle = 'white'; // couleur de dessin ctx.strokeStyle = 'white'; // couleur de dessin
ctx.stroke(); // dessin du contour ctx.stroke(); // dessin du contour
@ -411,7 +423,6 @@ socket.on('pong:point', (data) => {
return ; 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.fillStyle = 'red '; ctx.fillStyle = 'red ';
ctx.fill(); ctx.fill();
} }
@ -423,11 +434,6 @@ socket.on('pong:point', (data) => {
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// while (!gameId)
// ;
// Define a function to stop the drawing process
const stopDrawCanvas = async () => { const stopDrawCanvas = async () => {
running = false; running = false;
@ -437,32 +443,41 @@ socket.on('pong:point', (data) => {
{ {
console.log("stopDrawCanvas2") console.log("stopDrawCanvas2")
try{ try{
// const info = { await api.post('/status', {status: 1});
// id: myId,
// option: option,
// };
await api.post("deleteInvite", {username: gameParam.username}) await api.post("deleteInvite", {username: gameParam.username})
} }
catch (err){ catch (err){
console.log(err) console.log(err)
} }
} }
else
{
const data = {
myScore: myScore,
opScore: 5,
opName: opName,
opRank: opRank,
};
await api.post('/loss', data);
// await api.post('/status', {status: 1});
}
//here
socket.emit('pong:disconnect', {id: myId}); socket.emit('pong:disconnect', {id: myId});
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();
// Perform any necessary cleanup tasks
// ...
}; };
async function draw(timestamp: number) async function draw(timestamp: number)
{ {
console.log("turning, running= ", running); console.log("turning, running= ", running);
if (!running) if (!running)
{
window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong")
return ; return ;
}
if (!gameId || !canvas ) if (!gameId || !canvas )
{ {
// console.log("nogameid score= ", myScore);
requestAnimationFrame(draw); requestAnimationFrame(draw);
return ; return ;
} }
@ -479,9 +494,7 @@ async function draw(timestamp: number)
{ {
await api.post('/win', data); await api.post('/win', data);
await api.post('/status', {status: 1}); await api.post('/status', {status: 1});
//disconnect ?
socket.emit('pong:disconnect', {id: myId}); socket.emit('pong:disconnect', {id: myId});
console.log("send all ?? win"); console.log("send all ?? win");
} }
else else
@ -489,11 +502,9 @@ async function draw(timestamp: number)
await api.post('/loss', data); await api.post('/loss', data);
await api.post('/status', {status: 1}); await api.post('/status', {status: 1});
socket.emit('pong:disconnect', {id: myId}); 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 ;
} }
@ -504,7 +515,6 @@ async function draw(timestamp: number)
if (!ctx) if (!ctx)
return ; return ;
// requestAnimationFrame(draw);
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
drawPaddle(); drawPaddle();
drawcenter(); drawcenter();
@ -568,13 +578,11 @@ async function draw(timestamp: number)
} }
if (ballY - ballRadius - 2 <= 0 || ballY + ballRadius + 2 >= canvas.height) //touch up or down wall if (ballY - ballRadius - 2 <= 0 || ballY + ballRadius + 2 >= canvas.height) //touch up or down wall
{ {
// if ()
vY = -vY; vY = -vY;
if (ballY > (canvas.height / 2))//down wall if (ballY > (canvas.height / 2))//down wall
ballY = canvas.height - ballRadius - 2 ballY = canvas.height - ballRadius - 2
else else
ballY = ballRadius + 2 ballY = ballRadius + 2
// send_info();
} }
} }
@ -593,31 +601,15 @@ async function draw(timestamp: number)
} }
ballX = canvas.width / 2; ballX = canvas.width / 2;
ballY = canvas.height / 2; ballY = canvas.height / 2;
vX = 0; vX = 0.0005;
vY = 0; vY = 0;
hisScore += 1; hisScore += 1;
send_point(); send_point();
// send_forced_info();
} }
if (ballX > canvas.width) if (ballX > (canvas.width * 1.2) && ballX - (vX * 2) > canvas.width)
{ {
// if (ballX > canvas.width * 2) console.log("ball out win point pls")
// socket.emit send_my_point();
// console.log("win point")
// if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)
// {
// console.log('true hehe');
// ballX = paddleX + paddleWidth + ballRadius;
// updateVector();
// return ;
// }
// ballX = canvas.width / 2;
// ballY = canvas.height / 2;
// vX = 0;
// vY = 0;
// hisScore += 1;
// send_point();
// // send_forced_info();
} }
} }
@ -646,21 +638,14 @@ async function draw(timestamp: number)
document.addEventListener("touchmove", event => { document.addEventListener("touchmove", event => {
const touchY = event.touches[0].pageY; const touchY = event.touches[0].pageY;
// if (!lastTouchY)
// {
// vX = -0.01;
// lastTouchY = touchY;
// return;
// }
const newY = touchY > lastTouchY ? paddleY - (lastTouchY - touchY) : paddleY + (touchY - lastTouchY); const newY = touchY > lastTouchY ? paddleY - (lastTouchY - touchY) : paddleY + (touchY - lastTouchY);
updatePaddlePosition(newY); updatePaddlePosition(newY);
lastTouchY = touchY; lastTouchY = touchY;
send_paddle_info(); send_paddle_info();
}); });
document.addEventListener("keydown", event => { document.addEventListener("keydown", event => {
// console.log(event.code);
if (event.code === "ArrowUp") if (event.code === "ArrowUp")
{ {
if ((paddleY - paddleSpeed) > 0) if ((paddleY - paddleSpeed) > 0)
@ -673,50 +658,24 @@ async function draw(timestamp: number)
paddleY += paddleSpeed; // déplacer la raquette vers le bas paddleY += paddleSpeed; // déplacer la raquette vers le bas
send_paddle_info(); send_paddle_info();
} }
else if (event.code === "Space")//space else if (event.code === "KeyW")
{
console.log('vx change to -1');
vX = -0.0001;
// ballSpeed = 0.0001;
vY = 0;
send_forced_info();
// vX = 0.0001;
}
else if (event.code === "KeyE")
{
// console.log('vx change to -1');
vX = 0;
vY = 0;
ballX = canvas.width / 2;
ballY = canvas.height / 2;
send_forced_info();
}
else if (event.code === "KeyQ" )
{
if (vX < 0.003 * canvas.width && vX > -0.003 * canvas.width)
{
if (vX > 0)
vX += 0.0001;
else
vX -= 0.0001;
}
send_forced_info();
// console.log(`vx = ${vX}`);
}
else if (event.code === "KeyR")
{ {
let date = new Date();
console.log("last time =", date.getTime() - lastPower)
if (date.getTime() - lastPower < 15000)//10000 + 5000
return ;
if (!superpowerModifier) if (!superpowerModifier)
return ; return ;
paddleY = 0; paddleY = 0;
paddleHeight = canvas.height; paddleHeight = canvas.height;
use_power(); use_power();
setTimeout(() => { setTimeout(() => {
// code à exécuter après 5 secondes
paddleHeight = canvas.height * 0.25; paddleHeight = canvas.height * 0.25;
paddleY = canvas.height / 2 - paddleHeight / 2; paddleY = canvas.height / 2 - paddleHeight / 2;
console.log('Cinq secondes se sont écoulées.'); console.log('Cinq secondes se sont écoulées.');
}, 5000); }, 5000);
date = new Date();
lastPower = date.getTime();
} }
}); });

View File

@ -1,13 +0,0 @@
const reportWebVitals = onPerfEntry => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

View File

@ -3,17 +3,20 @@ import { useState, useEffect } from 'react'
import queryString from 'query-string'; import queryString from 'query-string';
import api from "./axiosApi.tsx"; import api from "./axiosApi.tsx";
import axios from 'axios'; import axios from 'axios';
import React from 'react';
import {Matchlog, User} from "../../interfaces.tsx"
function SuccessToken() { function SuccessToken() {
const location = useLocation(); const location = useLocation();
const { data } = queryString.parse(location.search); const { data } = queryString.parse(location.search);
const [code, setCode] = useState(''); const [code, setCode] = useState('');
const [user, setUser] = useState(false); const [user, setUser] = useState<User>();
useEffect(() => { useEffect(() => {
if (!data) { if (!data) {
console.log("No data"); console.log("No data");
return; return ;
} }
const cleanData = data.slice(1, -1); // Declare cleanData here const cleanData = data.slice(1, -1); // Declare cleanData here
@ -37,7 +40,7 @@ function SuccessToken() {
getUser(); getUser();
}, [data]); }, [data]);
const handleKeyPress = async (e)=>{ const handleKeyPress = async (e: { key: string; })=>{
// console.log(`e in press= ${e.key}`) // console.log(`e in press= ${e.key}`)
if (e.key !== "Enter") if (e.key !== "Enter")
return ; return ;
@ -90,7 +93,8 @@ function SuccessToken() {
// Render a loading indicator or return null while user is being fetched // Render a loading indicator or return null while user is being fetched
return <h1>Loading...</h1>; return <h1>Loading...</h1>;
} }
if (!data)
return (<></>);
const cleanData = data.slice(1, -1); // Declare cleanData here as well const cleanData = data.slice(1, -1); // Declare cleanData here as well
if (!user.otp_verified) { if (!user.otp_verified) {

View File

@ -5,19 +5,41 @@
background-color: black; background-color: black;
height: 100%; height: 100%;
} }
input.qr::-webkit-outer-spin-button,
input.qr::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input.qr{ input.qr{
width: 20%; width: auto;
border-radius: 5px; border-radius: 5px;
background-color: rgb(0, 0, 0); background-color: rgb(0, 0, 0);
margin : 1%; margin : 1%;
color:white; border-color:rgb(42, 41, 41);
border-style: solid;
border-width: 1px;
color: #ccc;
} }
.desactivate {
margin: 20%;
color: ghostwhite;
outline: 0;
border-radius: 100px;
padding: 2%;
background-image: linear-gradient(90deg, #5843e4, #5a0760);
border: 0;
font-size: x-large;
}
.App-logo { .App-logo {
height: 40vmin; height: 40vmin;
pointer-events: none; pointer-events: none;
} }
.centermargin
{
margin-left: 40px;
margin-right: 40px;
}
@media (prefers-reduced-motion: no-preference) { @media (prefers-reduced-motion: no-preference) {
.App-logo { .App-logo {
@ -48,3 +70,9 @@ input.qr{
transform: rotate(360deg); transform: rotate(360deg);
} }
} }
.friendRequest {
margin-left: 4vh;
stroke-width: 0.5;
font-size: x-large;
}

View File

@ -3,6 +3,7 @@
margin: 50px; margin: 50px;
} }
.rank_elements { .rank_elements {
border-width:1px; border-width:1px;
border-style:solid; border-style:solid;
@ -18,11 +19,23 @@
/* background-color: #5843e4; */ /* background-color: #5843e4; */
/* border-color: white; */ /* border-color: white; */
overflow: scroll; overflow: scroll;
height: 70vh; height: 68vh;
} }
.profilePic{ .profilePic{
margin-left: 10px;
/* margin-top: 10px; */
height: 30px; height: 30px;
width: 30px; width: 30px;
border-radius: 50%; border-radius: 50%;
} }
@media screen and (max-width: 755px){
.game{
display: grid;
height: 20vh;
}
.scroll{
height: 20vh;
}
}

View File

@ -22,7 +22,7 @@
display: grid; display: grid;
justify-content: center; justify-content: center;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
transition: 350ms; transition: 350ms;
/* margin-top: 10px; */ /* margin-top: 10px; */
@ -127,4 +127,5 @@ span {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} z-index: 1;
}

View File

@ -1,10 +1,10 @@
.home{ .home{
background-color: rgb(0, 0, 0); background-color: rgb(0, 0, 0);
height: 90vh; height: 70vh;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
select{ select{
@ -19,7 +19,8 @@ select{
border: 0!important; border: 0!important;
margin: 5px; margin: 5px;
font-size: 18px; font-size: 18px;
border-radius: 6px; padding: 5px;
border-radius: 1000px;
} }
.modal{ .modal{
@ -54,6 +55,7 @@ select{
height: 74vh; height: 74vh;
width: 30%; width: 30%;
overflow: scroll; overflow: scroll;
border-radius: 0px 0px 0px 10px;
/* width: 2rem; */ /* width: 2rem; */
/* height: 4rem; */ /* height: 4rem; */
} }
@ -65,7 +67,7 @@ select{
align-items: center; align-items: center;
justify-content: center; justify-content: center;
/* position:relative; */ /* position:relative; */
} }
.container{ .container{
@ -106,6 +108,19 @@ select{
margin-top: 0px; margin-top: 0px;
} }
.navbarSocial{
/* width: clamp(50%, 500px, 20%); */
/* height: min(50%, 100px); */
display: flex;
align-items: center;
/* background-color: yellow; */
margin: 10px;
background-image: linear-gradient(90deg, #5843e4, #5a0760);
color: white;
padding: 3px;
border-radius: 100px;
}
.pic{ .pic{
height: 35px; height: 35px;
width: 35px; width: 35px;
@ -131,16 +146,17 @@ select{
} }
.messages{ .messages{
background-color: rgb(26, 26, 26); /* background-color: rgb(26, 26, 26); */
/* height: calc(100% - 118px); */ /* height: calc(100% - 118px); */
width: 70%; width: 70%;
/* height: 300px; */ /* height: 300px; */
border-radius: 0px 0px 10px 0px;
overflow: scroll; overflow: scroll;
} }
.input{ .input{
display: flex; display: flex;
height: 50px; height: 6vh;
background-color: white; background-color: white;
color:#060b26; color:#060b26;
border: none; border: none;
@ -170,6 +186,7 @@ input{
width: 40px; width: 40px;
height: 40px; height: 40px;
border-radius: 50%; border-radius: 50%;
margin: 10px;
} }
.messageContent{ .messageContent{
@ -202,8 +219,19 @@ p {
text-decoration: none; text-decoration: none;
font-weight:lighter; font-weight:lighter;
margin: 1%; margin: 1%;
height: 25px;
} }
.playInvite{
margin: 5%;
color: ghostwhite;
outline: 0;
border-radius: 100px;
padding: 3%;
background-image: linear-gradient(90deg, #5843e4, #5a0760);
width: 42%;
font-size: x-large;
}
.darkSubmit{ .darkSubmit{
display: inline-block; display: inline-block;
color: white; color: white;
@ -228,9 +256,9 @@ p {
backdrop-filter: sepia(90%); backdrop-filter: sepia(90%);
background-color: rgba(0, 0, 0, 0.3); background-color: rgba(0, 0, 0, 0.3);
border-radius: 4px; border-radius: 4px;
width: 11rem; width: 15rem;
height: 1.5rem; height: 2rem;
margin-top: 1rem; margin-top: 1.3rem;
} }
.greenAlert{ .greenAlert{
@ -248,7 +276,7 @@ p {
color: rgba(255, 255, 255, 1); color: rgba(255, 255, 255, 1);
} }
.redAlert{ /* .redAlert{
width: clamp(50%, 500px, 90%); width: clamp(50%, 500px, 90%);
height: min(50%, 100px); height: min(50%, 100px);
@ -257,23 +285,30 @@ p {
border-radius: 12px; border-radius: 12px;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
text-align: center;
background-color: rgba(133, 6, 6, 0.7);
font-size: 25px;
color: rgba(255, 255, 255, 1);
} */
.redAlert{
width: clamp(50%, 500px, 90%);
height: min(50%, 100px);
margin: auto;
padding: 1rem;
border-radius: 12px;
flex-direction: row;
text-align: center;
/* align-items: center; */
background-color: rgba(133, 6, 6, 0.7); background-color: rgba(133, 6, 6, 0.7);
font-size: 25px; font-size: 25px;
color: rgba(255, 255, 255, 1); color: rgba(255, 255, 255, 1);
} }
.redAlert{ .text_alert{
width: clamp(50%, 500px, 90%); text-align: center;
height: min(50%, 100px); justify-content: center;
margin: auto;
padding: 1rem;
border-radius: 12px;
flex-direction: row;
align-items: center;
background-color: rgba(133, 6, 6, 0.7);
font-size: 25px;
color: rgba(255, 255, 255, 1);
} }
.yellowAlert{ .yellowAlert{
@ -285,17 +320,13 @@ p {
border-radius: 12px; border-radius: 12px;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
text-align: center;
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; flex-wrap: wrap;
} }
.yellowAlert::p {
overflow-wrap: break-word;
max-width: 1000px;
}
.modalSetting{ .modalSetting{
width: clamp(50%, 700px, 90%); width: clamp(50%, 700px, 90%);
height: min(50%, 300px); height: min(50%, 300px);
@ -307,11 +338,17 @@ p {
/* flex-direction: column; */ /* flex-direction: column; */
/* align-items: center; */ /* align-items: center; */
background-color: #3e3c61; background-color: #3e3c61;
overflow: scroll;
} }
.settingFirstPart{ .settingFirstPart{
margin-top: 10%; margin-top: 10%;
margin-left: 15%; margin-left: 20%;
}
.settingFirstPart2{
margin-top: 10%;
margin-left: 30%;
} }
.settingSecondPart{ .settingSecondPart{
@ -324,6 +361,7 @@ p {
.checkbox{ .checkbox{
display:flex; display:flex;
flex-direction:row; flex-direction:row;
margin-left: 60px;
} }
input.in{ input.in{
@ -331,23 +369,59 @@ input.in{
margin-left: 0px; margin-left: 0px;
background-color: black; background-color: black;
color: white; color: white;
border-radius: 12px; border-radius: 4px;
width: 70%; width: 70%;
height: 100%;
font-weight:100;
font-size: 20px;
padding: 7px;
} }
input.in_howLong{ input.in_howLong{
margin-top: 14.5%; margin-top: 13%;
margin-left: 0px; margin-left: 0px;
background-color: black; background-color: black;
color: white; color: white;
border-radius: 12px; border-radius: 4px;
width: 15%; width: 10%;
height: 10%;
font-weight:100;
font-size: 20px;
padding: 7px;
} }
.mdp{ .mdp{
background-color : black; background-color : black;
border-radius: 8px; border-radius: 8px;
color: white; color: white;
width: 20%; width: 60%;
height: 30%;
} }
.case{
height: auto;
width: auto;
margin-left: 10px;
}
.catchat{
font-size: 30px;
margin-left: 12px;
}
.block{
font-size: 25px;
margin-left: 12px;
margin-top: 0.2rem;
}
.inside_ckeckbox{
height: 25px;
margin-left: -50px;
}
h2{
overflow-wrap: break-word;
max-width: 200px;
}

View File

@ -62,6 +62,7 @@
.page { .page {
text-align: center; text-align: center;
overflow-y: scroll; overflow-y: scroll;
/* height: 80vh; */
/* height: 50vh; */ /* height: 50vh; */
/* width: 50vh; */ /* width: 50vh; */
/* background-color: black; */ /* background-color: black; */
@ -80,9 +81,9 @@
border-radius: 50%; border-radius: 50%;
border: thick; border: thick;
border-color: red; border-color: red;
margin-left: 20px;
/* border-image: linear-gradient(90deg, #5843e4, #5a0760); */ /* border-image: linear-gradient(90deg, #5843e4, #5a0760); */
/* margin-top: 20px; */
} }
.home{ .home{
@ -96,11 +97,11 @@
} }
.history{ .history{
display: inline-block; display:inline-block;
color: white; color: white;
background-color: #5843e4; background-color: #5843e4;
border-radius: 20px; border-radius: 20px;
padding: 14px; padding: 1.3% 30%;
font-size: 1.7rem; font-size: 1.7rem;
text-decoration: none; text-decoration: none;
font-weight: bold; font-weight: bold;
@ -153,6 +154,13 @@
text-decoration: none; text-decoration: none;
font-weight: bold; font-weight: bold;
} }
.user_name{
/* background-image: linear-gradient(90deg, #5843e4, #5a0760); */
background: -webkit-linear-gradient(60deg, #5843e4, #5a0760);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
/* canvas { /* canvas {
margin-top: 20px; margin-top: 20px;
border: solid 0px #ccc; border: solid 0px #ccc;

View File

@ -1,20 +1,20 @@
.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;
} }
.inside_checkbox{
height : 70%;
width: 70%;
}
.field { .field {
background-color: rgb(249, 249, 249); background-color: rgb(249, 249, 249);
@ -69,6 +69,18 @@
} }
} }
.responsive{
display: flex;
flex-direction: column;
}
/* @media screen and (max-width: 350px){
.responsive{
display:list-item;
flex-direction: column;
}
} */
#myCanvas { #myCanvas {
background-color: rgb(124, 47, 47); background-color: rgb(124, 47, 47);
/* position: absolute; */ /* position: absolute; */
@ -94,4 +106,4 @@
height: 100%; height: 100%;
width: 100%; width: 100%;
} */ } */
/* } */ /* } */

View File

@ -3,6 +3,7 @@ version: "3.3"
services: services:
nginx: nginx:
restart: unless-stopped
image: nginx:alpine image: nginx:alpine
container_name: nginx container_name: nginx
env_file: .env env_file: .env
@ -14,20 +15,11 @@ services:
- 8080:8080 - 8080:8080
volumes: volumes:
- ./conf/nginx.conf:/etc/nginx/conf.d/default.conf - ./conf/nginx.conf:/etc/nginx/conf.d/default.conf
# volumes:
# - "./conf:/etc/nginx/templates/"
# ports:
# - 80:80
# volumes:
# - ./conf/nginx.conf:/etc/nginx/conf.d/default.conf
# command: sh -c "envsubst < /etc/nginx/conf.d/default.conf > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
# - ./containers/frontend:/var/www/html
networks: networks:
- pongNetwork - pongNetwork
react_app: react_app:
restart: unless-stopped
image: node:latest image: node:latest
container_name: react_app container_name: react_app
working_dir: /app working_dir: /app
@ -44,6 +36,7 @@ services:
api: api:
restart: unless-stopped
image: node:latest image: node:latest
container_name: api container_name: api
working_dir: /app working_dir: /app
@ -59,9 +52,9 @@ services:
entrypoint: ["sh", "-c" , "npm install && npm run start:dev"] entrypoint: ["sh", "-c" , "npm install && npm run start:dev"]
postgresql: postgresql:
restart: unless-stopped
env_file: .env env_file: .env
image: postgres:14.1-alpine image: postgres:14.1-alpine
restart: unless-stopped
container_name: postgresql container_name: postgresql
environment: environment:
- POSTGRES_USER=postgres - POSTGRES_USER=postgres
@ -75,6 +68,7 @@ services:
- pongNetwork - pongNetwork
pong: pong:
restart: unless-stopped
image: node:latest image: node:latest
container_name: pong container_name: pong
working_dir: /app working_dir: /app
@ -88,6 +82,7 @@ services:
entrypoint: ["sh", "-c" , "npm install && npm run start:dev"] entrypoint: ["sh", "-c" , "npm install && npm run start:dev"]
chat: chat:
restart: unless-stopped
image: node:latest image: node:latest
container_name: chat container_name: chat
working_dir: /app working_dir: /app