From 3ca457a3801f18356bf09724192b5d1f6c374527 Mon Sep 17 00:00:00 2001 From: kinou-p Date: Sun, 18 Jun 2023 21:43:19 +0200 Subject: [PATCH 01/13] reload when create conv --- .env | 6 +++--- containers/api/src/app.controller.ts | 4 +++- containers/react/.env | 3 ++- containers/react/src/components/Messages/Modal.tsx | 5 +++-- containers/react/src/pages/Login42.tsx | 2 +- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.env b/.env index aae0c767..4b96a475 100644 --- a/.env +++ b/.env @@ -14,9 +14,9 @@ NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf" # BASE_URL=http://localhost -BASE_URL=localhost -REACT_APP_BASE_URL=localhost -REDIRECT_URI=http://localhost/api/auth/login +BASE_URL=92.143.191.152 +REACT_APP_BASE_URL=92.143.191.152 +REDIRECT_URI=http://92.143.191.152/api/auth/login #postgres var # POSTGRES_HOST=127.0.0.1 # DB_TYPE=postgres diff --git a/containers/api/src/app.controller.ts b/containers/api/src/app.controller.ts index 9183cb2b..477ccdd0 100644 --- a/containers/api/src/app.controller.ts +++ b/containers/api/src/app.controller.ts @@ -6,7 +6,7 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/17 01:00:00 by apommier #+# #+# */ -/* Updated: 2023/06/18 13:30:50 by apommier ### ########.fr */ +/* Updated: 2023/06/18 17:45:39 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -419,6 +419,8 @@ export class AppController { if (!amIhere) 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); diff --git a/containers/react/.env b/containers/react/.env index 3b0e2b83..07066191 100644 --- a/containers/react/.env +++ b/containers/react/.env @@ -1,2 +1,3 @@ -REACT_APP_BASE_URL=localhost +# REACT_APP_BASE_URL=localhost +REACT_APP_BASE_URL=92.143.191.152 # REACT_APP_BASE_URL=192.168.1.19 \ No newline at end of file diff --git a/containers/react/src/components/Messages/Modal.tsx b/containers/react/src/components/Messages/Modal.tsx index 62b50811..deda5cae 100644 --- a/containers/react/src/components/Messages/Modal.tsx +++ b/containers/react/src/components/Messages/Modal.tsx @@ -77,7 +77,7 @@ const Modal = ({handleClose}) => { } }; - const saveSelectedOptions = () => { + const saveSelectedOptions = async () => { // const selectedOptions = selectTags.map((tag) => tag.selectedOption); const selectedOptions = selectTags.map((tag) => tag.selectedOption).filter((option) => option !== ''); @@ -88,8 +88,9 @@ const Modal = ({handleClose}) => { } try{ // test - api.post("/conv", data); + await api.post("/conv", data); handleClose(); + window.location.reload(false); } catch(err) { console.log(err); } diff --git a/containers/react/src/pages/Login42.tsx b/containers/react/src/pages/Login42.tsx index 4d8ae2e2..c3bfbc8f 100644 --- a/containers/react/src/pages/Login42.tsx +++ b/containers/react/src/pages/Login42.tsx @@ -18,7 +18,7 @@ function Login42() client_id: 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41', client_secret: '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', code: code, - redirect_uri: 'http://localhost:8080/login42', + redirect_uri: 'http://' + process.env.REACT_APP_BASE_URL + '/login42', }; axios.post('https://api.intra.42.fr/oauth/token', data) From 8d6e3e95b3a5a6b3fe1738a2f0be79e0b5693760 Mon Sep 17 00:00:00 2001 From: kinou-p Date: Sun, 18 Jun 2023 21:45:02 +0200 Subject: [PATCH 02/13] little error canvas --- containers/react/package-lock.json | 15 +++++++++------ containers/react/package.json | 3 +++ containers/react/src/pages/canvas.tsx | 5 ++++- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/containers/react/package-lock.json b/containers/react/package-lock.json index a0474a11..71a0b93a 100644 --- a/containers/react/package-lock.json +++ b/containers/react/package-lock.json @@ -25,6 +25,9 @@ "styled-components": "^5.3.10", "typescript": "^3.2.1", "web-vitals": "^2.1.4" + }, + "devDependencies": { + "@types/node": "^20.3.1" } }, "node_modules/@adobe/css-tools": { @@ -4535,9 +4538,9 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "node_modules/@types/node": { - "version": "20.1.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.4.tgz", - "integrity": "sha512-At4pvmIOki8yuwLtd7BNHl3CiWNbtclUbNtScGx4OHfBd4/oWoJC8KRCIxXwkdndzhxOsPXihrsOoydxBjlE9Q==" + "version": "20.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", + "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -24452,9 +24455,9 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "@types/node": { - "version": "20.1.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.4.tgz", - "integrity": "sha512-At4pvmIOki8yuwLtd7BNHl3CiWNbtclUbNtScGx4OHfBd4/oWoJC8KRCIxXwkdndzhxOsPXihrsOoydxBjlE9Q==" + "version": "20.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", + "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" }, "@types/parse-json": { "version": "4.0.0", diff --git a/containers/react/package.json b/containers/react/package.json index 0f333105..f0205289 100644 --- a/containers/react/package.json +++ b/containers/react/package.json @@ -45,5 +45,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "@types/node": "^20.3.1" } } diff --git a/containers/react/src/pages/canvas.tsx b/containers/react/src/pages/canvas.tsx index 857d582d..6ff0f0a3 100644 --- a/containers/react/src/pages/canvas.tsx +++ b/containers/react/src/pages/canvas.tsx @@ -28,7 +28,10 @@ function DrawCanvas(option) { const socket = io('http://' + process.env.REACT_APP_BASE_URL + ':4000'); // const socket = socketRef.current console.log("start function"); - const canvas = document.getElementById('myCanvas'); + + let canvas; + canvas = document.getElementById('myCanvas'); + const ctx = canvas.getContext('2d'); // useEffect(() => { From 0c04e29cc748e5a7be8b437e584c0208e7e17490 Mon Sep 17 00:00:00 2001 From: kinou-p Date: Mon, 19 Jun 2023 22:07:06 +0200 Subject: [PATCH 03/13] fix error everywhere fix name, pong private party, blocked effective ? --- .env | 6 +- containers/api/src/app.controller.ts | 101 ++++-- containers/api/src/auth/login42.ts | 1 + containers/api/src/model/user.entity.ts | 6 + containers/chat/src/chat/chat.gateway.ts | 20 +- containers/pong/src/pong/pong.gateway.ts | 255 +++++++------ containers/react/.env | 6 +- containers/react/src/components/Game/Rank.tsx | 10 +- .../react/src/components/Game/Ranking.tsx | 2 +- .../react/src/components/Messages/Chats.tsx | 111 ++++-- .../src/components/Messages/GameModal.tsx | 142 ++++++++ .../react/src/components/Messages/Message.tsx | 48 ++- .../react/src/components/Messages/Modal.tsx | 26 +- .../src/components/Messages/ModalSetting.tsx | 10 +- .../PartyInvite.tsx} | 43 ++- .../react/src/components/Profile/EditName.tsx | 26 +- .../src/components/Sidebar/SidebarData.tsx | 2 +- .../src/components/Social/Friend.tsx~HEAD | 111 ------ .../src/components/Social/FriendRequest.tsx | 1 + containers/react/src/pages/Field.tsx | 28 +- containers/react/src/pages/Home.tsx | 13 +- containers/react/src/pages/Login42.tsx | 7 +- containers/react/src/pages/canvas.tsx | 340 +++++++++++------- containers/react/src/styles/Profile.css | 65 ++++ 24 files changed, 886 insertions(+), 494 deletions(-) create mode 100644 containers/react/src/components/Messages/GameModal.tsx rename containers/react/src/components/{Social/FriendRequest.tsx~HEAD => Messages/PartyInvite.tsx} (59%) delete mode 100644 containers/react/src/components/Social/Friend.tsx~HEAD diff --git a/.env b/.env index 4b96a475..aae0c767 100644 --- a/.env +++ b/.env @@ -14,9 +14,9 @@ NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf" # BASE_URL=http://localhost -BASE_URL=92.143.191.152 -REACT_APP_BASE_URL=92.143.191.152 -REDIRECT_URI=http://92.143.191.152/api/auth/login +BASE_URL=localhost +REACT_APP_BASE_URL=localhost +REDIRECT_URI=http://localhost/api/auth/login #postgres var # POSTGRES_HOST=127.0.0.1 # DB_TYPE=postgres diff --git a/containers/api/src/app.controller.ts b/containers/api/src/app.controller.ts index 477ccdd0..47c17ed7 100644 --- a/containers/api/src/app.controller.ts +++ b/containers/api/src/app.controller.ts @@ -6,7 +6,7 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/17 01:00:00 by apommier #+# #+# */ -/* Updated: 2023/06/18 17:45:39 by apommier ### ########.fr */ +/* Updated: 2023/06/19 19:48:52 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,6 +27,7 @@ import { generateOTP } from './users/2fa'; import { VerifyOTP } from './users/2fa'; import { ValidateOTP } from './users/2fa'; import { privateDecrypt } from 'crypto'; +import { formatWithOptions } from 'util'; //2fa @@ -128,6 +129,8 @@ export class AppController { async newBlocked(@Request() req, @Body() data: any) { // return await this.userService.getFriends(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); } @@ -136,6 +139,8 @@ export class AppController { @Post('/invite') async newInvite(@Request() req, @Body() data: any) { console.log(`user= ${req.user.username}`) + if (data.username === req.user.username) + return (0); const user = await this.userService.findOne(data.username) if (!user) return (0); @@ -270,6 +275,44 @@ export class AppController { return await this.userService.getRanking(); } + @UseGuards(JwtAuthGuard) + @Post('/partyInvite') + async partyInvite(@Request() req, @Body() data: any) + { + //find data.username and add invite to list + console.log("data post priv invite=", data); + const user = await this.userService.findOne(data.username); + user.partyInvite = user.partyInvite || []; + user.partyInvite.push({ username: req.user.username, gameId: data.gameId }); + console.log("usr === ", user) + await this.userService.save(user); + // user.partyInvite.push(data); + console.log("invite === ", user.partyInvite) + } + + @UseGuards(JwtAuthGuard) + @Get('/partyInvite') + async getPartyInvite(@Body() data: any) + { + //find data.username and add invite to list + const user = await this.userService.findOne(data.username); + user.partyInvite = user.partyInvite || []; + // this.userService.save(user); + // user.partyInvite.push(data); + // console.log("data invite === ", data.username) + return user.partyInvite; + } + + @UseGuards(JwtAuthGuard) + @Post('/deleteInvite') + async deleteInvite(@Request() req, @Body() data: any) + { + console.log("delete invite user= ", data.username) + const user = await this.userService.findOne(data.username); + user.partyInvite = user.partyInvite.filter(item => Object.values(item)[1] !== req.user.username); + this.userService.save(user); + } + @UseGuards(JwtAuthGuard) @Post('/history') async getHistory(@Body() data: any) @@ -441,6 +484,13 @@ export class AppController { 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) { @@ -479,12 +529,6 @@ export class AppController { // res.json(messages); - } - - @UseGuards(JwtAuthGuard) - @Post('/ban') - async banUser(@Body() data: any) { - return await this.chatService.banUser(data.convId, data.username) } @UseGuards(JwtAuthGuard) @@ -495,30 +539,48 @@ export class AppController { return await this.chatService.setName(data.convId, data.name) } - @UseGuards(JwtAuthGuard) - @Post('/invite') - async inviteUser(@Body() data: any) { - return await this.chatService.inviteUser(data.convId, data.username) - } - @UseGuards(JwtAuthGuard) @Post('/password') async setPassword(@Body() data: any) { - return await this.chatService.setPassword(data.convId, data.password) + 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) - } - + return await this.chatService.verifyPassword(data.convId, data.password) + } + + @UseGuards(JwtAuthGuard) + @Post('/invite') + async inviteUser(@Body() data: any) { + return await this.chatService.inviteUser(data.convId, data.username) + } + + @UseGuards(JwtAuthGuard) + @Post('/ban') + async banUser(@Body() data: any) { + if (!data.username) + return ; + return await this.chatService.banUser(data.convId, data.username) + } + @UseGuards(JwtAuthGuard) @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) { @@ -526,11 +588,6 @@ export class AppController { return await this.chatService.isAdmin(data.convId, req.user.username) } - @UseGuards(JwtAuthGuard) - @Post('/mute') - async muteUser(@Body() data: any) { - return await this.chatService.muteUser(data.convId, data.username) - } @UseGuards(JwtAuthGuard) @Post('/private') diff --git a/containers/api/src/auth/login42.ts b/containers/api/src/auth/login42.ts index 8f44f2e4..165bd7fb 100644 --- a/containers/api/src/auth/login42.ts +++ b/containers/api/src/auth/login42.ts @@ -58,6 +58,7 @@ export class loginClass { console.log(`no user, creating one`); user = { id: null, + partyInvite: null, password: null, username: userName, nickname: userName, diff --git a/containers/api/src/model/user.entity.ts b/containers/api/src/model/user.entity.ts index 5ddd7709..5fd7c12b 100644 --- a/containers/api/src/model/user.entity.ts +++ b/containers/api/src/model/user.entity.ts @@ -65,6 +65,12 @@ export class User { @Column('text', { array: true, nullable: true }) friendRequest: string[]; + @Column({ type: 'jsonb', nullable: true }) + partyInvite: Record[]; + + // @Column('text', { array: true, nullable: true }) + // friendRequest: string[]; + @Column('text', { array: true, nullable: true }) friends: string[]; diff --git a/containers/chat/src/chat/chat.gateway.ts b/containers/chat/src/chat/chat.gateway.ts index 3bd1d321..0f44fe1f 100644 --- a/containers/chat/src/chat/chat.gateway.ts +++ b/containers/chat/src/chat/chat.gateway.ts @@ -8,15 +8,19 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa @WebSocketServer() server: Server; + private clients: Record = {}; // private clientsNames: Record = {}; private clientsNames: Map = new Map(); // private games: Map = new Map();// Chat en cours, identifiées par un ID + + afterInit(server: Server) { console.log('ChatGateway initialized'); } + handleConnection(client: Socket, ...args: any[]) { @@ -92,18 +96,12 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa console.log("create") this.clientsNames.set(payload.username, [client.id]); // Create a new array with the new client as the value } - // let clientLenght = Object.keys(this.clientsNames[payload.username]).length - // const clientArray = this.clientsNames.get(payload.username) - // let clientLenght = clientArray. - // console.log(`lenght= ${clientLenght}`) - - // this.clientsNames[payload.username][clientLenght] = this.clients[client.id]; - // console.log(`clients: ${Object.keys(this.clientsNames).length}`) - // this.clients[clientId] = client; - - //add a new client with socket and name for key - //payload.username } + + @SubscribeMessage('socket.io') + socketConnect(client: any, payload: any): void { + console.log("/socket.io") +} // @SubscribeMessage('sendMessage') diff --git a/containers/pong/src/pong/pong.gateway.ts b/containers/pong/src/pong/pong.gateway.ts index de0e259b..a136302d 100644 --- a/containers/pong/src/pong/pong.gateway.ts +++ b/containers/pong/src/pong/pong.gateway.ts @@ -1,7 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pong.gateway.ts :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: apommier +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/06/19 15:18:38 by apommier #+# #+# */ +/* Updated: 2023/06/19 21:38:55 by apommier ### ########.fr */ +/* */ +/* ************************************************************************** */ + import { SubscribeMessage, WebSocketGateway, OnGatewayInit, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets'; import { Server, Socket } from 'socket.io'; import { v4 as uuidv4 } from 'uuid'; + +//======================================================================================================== +//======================================================================================================== +// Connection/Disconnection +//======================================================================================================== +//======================================================================================================== + @WebSocketGateway({ cors: true }) export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect { @WebSocketServer() server: Server; @@ -31,7 +50,8 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa handleDisconnect(client: Socket) { - console.log(`Client disconnected: ${client.id}`); + // console.log(`Client disconnected: ${client.id}`); + console.log(`Normal disconnected: ${client.id}`); // this.waitingClients.delete(client); this.waitingClients.forEach((waitingClient) => { if (waitingClient.client === client) { @@ -41,40 +61,65 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa console.log(`Total connected clients: ${Object.keys(this.clients).length}`); } - // @SubscribeMessage('pong:matchmaking') - // addMatchmaking(client: Socket, payload: any): void - // { - // console.log("matchmaking"); - // console.log(payload); - // // this.waitingClients.add(client); - // this.waitingClients.add(client); - // console.log("Adding client to waiting list..."); - // if (this.waitingClients.size >= 2) { - // console.log("Creating new game..."); - // const players = Array.from(this.waitingClients).slice(0, 2); - // players.forEach((player) => { - // this.waitingClients.delete(player); - // }); - // const gameId = uuidv4(); - // this.games.set(gameId, players); - // players.forEach((player) => { - // player.join(gameId); - // console.log(`Player ${player.id} joined game ${gameId}`); - // }); - // players.forEach((player) => { - // // const playersIds = game.map(socket => socket.id); - // player.emit('pong:gameId', gameId); - // }); - // } - // // console.log(`from: ${client.id}`); - // } - @SubscribeMessage('pong:invite') - createPrivateGame(client: Socket, payload: any): void { - //after invite accepted ? - //set the two user in a game ? + @SubscribeMessage('pong:disconnect') + disconnectClient(client: Socket, payload: any): void { + console.log("disconnect forced client= ", client.id) + + for (const key in this.clients) { + if (this.clients.hasOwnProperty(key) && this.clients[key] === client) + delete this.clients[key]; + } + + // Delete the socket from the 'waitingClients' set + this.waitingClients.forEach((item) => { + if (item.client === client) + this.waitingClients.delete(item); + }); + + // Delete the socket from the 'games' map + this.games.forEach((sockets, gameId) => { + const index = sockets.indexOf(client); + if (index !== -1) + { + + if (index === 0) + { + console.log("emit boy1") + sockets[1].emit("pong:win") + // sockets[0].emit("/win") + } + else + { + console.log("emit boy2") + sockets[0].emit("pong:win") + // sockets[1].emit("/win") + } + // let playersIds = + // const playersIds = this.games.get(gameId).map(socket => socket.id); + // // if (playersIds[0] === payload.id) + // // { + // if (this.clients[playersIds[1]]) + // this.clients[playersIds[1]].emit('pong:win'); + // if (this.clients[playersIds[0]]) + // this.clients[playersIds[0]].emit('pong:win'); + // } + // if (playersIds[1] === payload.id) + // { + // } + //send victory to the other one + this.games.delete(gameId); + delete this.clients[client.id]; + } + + }) } +//======================================================================================================== +//======================================================================================================== +// Matchmaking +//======================================================================================================== +//======================================================================================================== @SubscribeMessage('pong:matchmaking') addMatchmaking(client: Socket, payload: any): void { @@ -91,6 +136,7 @@ addMatchmaking(client: Socket, payload: any): void { waitingClient.option === payload.option && waitingClient.client !== client ); + if (matchingClients.length > 0) { console.log("Creating new game..."); const players = [matchingClients[0].client, client]; // Add the current client to the players array @@ -117,43 +163,76 @@ addMatchmaking(client: Socket, payload: any): void { player.emit('pong:gameId', gameId); }); } + // console.log(`from: ${client.id}`); } - // @SubscribeMessage('pong:message') - // handleMessage(client: Socket, payload: any): void - // { - // console.log(`from: ${client.id}`); - // console.log(payload); - - // const game = this.games.get(payload.gameId); - // const playersIds = game.map(socket => socket.id); - // // const players = Object.keys(game); - // // if (Object.keys(this.clients).length === 2) - // // { - // // const clientIds = Object.keys(this.clients); - // // console.log(`id of 0= ${clientIds[0]}`); - - // // payload.ballX - // // payload.ballY - // // payload. - - // if (clientIds[0] === payload.id) - // { - // // console.log("client 0 true"); - // if (payload.ballX <= payload.width / 2) - // this.clients[clientIds[1]].emit('pong:info', payload); - // } - // else if (clientIds[1] === payload.id) - // { - // if (payload.ballX < payload.width / 2) - // this.clients[clientIds[0]].emit('pong:info', payload); - // // console.log("client 0 true"); - // } - // // } - // console.log("END OF HANDLE"); - // } + +//======================================================================================================== +//======================================================================================================== +// Private Match +//======================================================================================================== +//======================================================================================================== + + + +// @SubscribeMessage('pong:invite') +// createPrivateGame(client: Socket, payload: any): void { +// //after invite accepted ? +// //set the two user in a game ? + +// } + + +@SubscribeMessage('pong:joinParty') +joinPrivateParty(client: Socket, payload: any): void { + console.log(" join PrivateParty") + + const game = this.games.get(payload.gameId); + if (game) + { + game.push(client); + const playersIds = game.map(socket => socket.id); + this.clients[playersIds[0]].emit('pong:gameId', payload.gameId); + this.clients[playersIds[1]].emit('pong:gameId', payload.gameId); + } + else + { + console.log("emit else") + client.emit("pong:win") + } + // console.log("no game ???") + +} + + +@SubscribeMessage('pong:privateParty') +addPrivateParty(client: Socket, payload: any): void { + console.log("addPrivateParty") + + const gameId = uuidv4(); + const players = [client]; + this.games.set(gameId, players); + console.log("game created private") + client.emit('pong:privateId', gameId); + //create game + //emit private gameId to canvas (don't launch canvas) + +} + + + + + + +//======================================================================================================== +//======================================================================================================== +// In Game +//======================================================================================================== +//======================================================================================================== + + @SubscribeMessage('pong:power') sendPower(client: Socket, payload: any): void @@ -191,29 +270,6 @@ addMatchmaking(client: Socket, payload: any): void { console.log("END OF HANDLE"); } - // @SubscribeMessage('pong:forced') - // forcedMessage(client: Socket, payload: any): void - // { - // console.log(`from: ${client.id}`); - // console.log(payload); - - // if (Object.keys(this.clients).length === 2) - // { - // const clientIds = Object.keys(this.clients); - // console.log(`id of 0= ${clientIds[0]}`); - - // if (clientIds[0] === payload.id) - // { - // this.clients[clientIds[1]].emit('pong:info', payload); - // } - // else if (clientIds[1] === payload.id) - // { - // this.clients[clientIds[0]].emit('pong:info', payload); - // } - // } - // console.log("END OF HANDLE"); - // } - @SubscribeMessage('pong:forced') forcedMessage(client: Socket, payload: any): void { @@ -236,29 +292,6 @@ addMatchmaking(client: Socket, payload: any): void { console.log("END OF HANDLE"); } - // @SubscribeMessage('pong:paddle') - // handlePaddle(client: Socket, payload: any): void - // { - // console.log(`from: ${client.id}`); - // console.log(payload); - - // if (Object.keys(this.clients).length === 2) - // { - // const clientIds = Object.keys(this.clients); - // console.log(`id of 0= ${clientIds[0]}`); - - // if (clientIds[0] === payload.id) - // { - // this.clients[clientIds[1]].emit('pong:paddle', payload); - // } - // else if (clientIds[1] === payload.id) - // { - // this.clients[clientIds[0]].emit('pong:paddle', payload); - // } - // } - // console.log("END OF HANDLE"); - // } - @SubscribeMessage('pong:paddle') handlePaddle(client: Socket, payload: any): void { diff --git a/containers/react/.env b/containers/react/.env index 07066191..35542322 100644 --- a/containers/react/.env +++ b/containers/react/.env @@ -1,3 +1,5 @@ -# REACT_APP_BASE_URL=localhost -REACT_APP_BASE_URL=92.143.191.152 +REACT_APP_BASE_URL=localhost +REACT_APP_API_SECRET=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 +REACT_APP_CLIENT_UID=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41 +# REACT_APP_BASE_URL=92.143.191.152 # REACT_APP_BASE_URL=192.168.1.19 \ No newline at end of file diff --git a/containers/react/src/components/Game/Rank.tsx b/containers/react/src/components/Game/Rank.tsx index 12f62d6d..b65e297d 100644 --- a/containers/react/src/components/Game/Rank.tsx +++ b/containers/react/src/components/Game/Rank.tsx @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* Rank.jsx :+: :+: :+: */ +/* Rank.tsx :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/09 08:49:24 by apommier #+# #+# */ -/* Updated: 2023/06/09 08:55:22 by apommier ### ########.fr */ +/* Updated: 2023/06/19 20:35:39 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -36,10 +36,12 @@ function Rank({user, index}){ fetchProfilePicture(); }) + // console.log(index); return (
-
-

{index + 1}

+
+ {/*

{(index + 1).toString()}

*/} +

{(index + 1)}

{user.rank}: {user.nickname} {profilePicture ? ( diff --git a/containers/react/src/components/Game/Ranking.tsx b/containers/react/src/components/Game/Ranking.tsx index 168952c5..aa564f08 100644 --- a/containers/react/src/components/Game/Ranking.tsx +++ b/containers/react/src/components/Game/Ranking.tsx @@ -41,7 +41,7 @@ function Ranking(){ //

Ranking

{ranking.map((user, index) => ( - + // return ( //
//
diff --git a/containers/react/src/components/Messages/Chats.tsx b/containers/react/src/components/Messages/Chats.tsx index b35450cd..9f5015c2 100644 --- a/containers/react/src/components/Messages/Chats.tsx +++ b/containers/react/src/components/Messages/Chats.tsx @@ -6,6 +6,7 @@ import DefaultPic from '../../assets/profile.jpg' import api from '../../script/axiosApi.tsx'; import { motion , AnimatePresence} from "framer-motion"; import Modal from "./Modal.tsx"; +import GameModal from "./GameModal.tsx"; import Message from "./Message.tsx" // import Input from "./Input"; @@ -22,6 +23,7 @@ import GreenAlert from "../Alert/GreenAlert.tsx"; import RedAlert from "../Alert/RedAlert.tsx"; import YellowAlert from "../Alert/YellowAlert"; import ModalSetting from "./ModalSetting.tsx"; +import PartyInvite from "./PartyInvite.tsx"; const TouchDiv = styled.div` @@ -75,6 +77,7 @@ function Chats(){ const [isLoading, setIsLoading] = useState(true); const [conversations, setConversation] = useState([]); + const [partyInvite, setPartyInvite] = useState([]); const [user, setUser] = useState(null); const [currentChat, setCurrentChat] = useState(false); // false is good? const [isAdmin, setIsAdmin] = useState(false); // false is good? @@ -82,7 +85,9 @@ function Chats(){ const [messages, setMessage] = useState([]); const [newMessages, setNewMessage] = useState(""); const [incomingMessage, setIncomingMessage] = useState(""); - const socket = useRef(); + + let socket; + socket = useRef(); @@ -91,24 +96,30 @@ function Chats(){ const getConv = async ()=>{ try{ const convs = await api.get("/conv") + const tmpInvite = await api.get("/partyInvite") const tmpUser = await api.get("/profile") console.log(convs); + + // console.log("invite data use effect= ", tmpInvite.data); + setPartyInvite(tmpInvite.data); setUser(tmpUser.data); setConversation(convs.data); - socket.current = io('http://' + process.env.REACT_APP_BASE_URL + ':4001'); - console.log(`connection....`); + // console.log(`connection....`); + socket.current = io('http://' + process.env.REACT_APP_BASE_URL + ':4001', { transports: ['polling'] }); + // console.log(`connection done`); socket.current.emit('connection', {username: tmpUser.data.username}) socket.current.on('message', (data) => { //data should be a message ? - console.log(`message received data= ${data.sender}`) - console.log(`message received data= ${data.convId}`) - console.log(`message received data= ${data.sender}`) - console.log(`current chat = ${currentChat}`) + // console.log(`message received data= ${data.sender}`) + // console.log(`message received data= ${data.convId}`) + // console.log(`message received data= ${data.sender}`) + // console.log(`current chat = ${currentChat}`) setIncomingMessage(data); }); setIsLoading(false) } catch(err){ + console.log("ERRORRRRR") console.log(err); } }; @@ -135,8 +146,11 @@ function Chats(){ // console.log(`result1 = ${currentChat.id !== incomingMessage.convId}`) if (currentChat !== null && 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(); @@ -169,17 +183,10 @@ function Chats(){ members: null }; try{ - console.log(`id= ${currentChat.id}`) - const allowed = await api.post('/allowed', {convId: message.convId, username: user.username}); - console.log("allowed= ", allowed.data) - if (!allowed.data) - return ; const res = await api.post('/message', message); const convMember = await api.post('/member', message); message.members = convMember.data.members; - console.log(convMember); - // console.log(`currentChat= ${currentChat.id}`) - + message.id = res.data.id setMessage([...messages, res.data]); setNewMessage(""); socket.current.emit('sendMessage', message); @@ -201,13 +208,10 @@ function Chats(){ members: null }; try{ - console.log(`id= ${currentChat.id}`) const res = await api.post('/message', message); const convMember = await api.post('/member', message); message.members = convMember.data.members; - console.log(convMember); - // console.log(`currentChat= ${currentChat.id}`) - + message.id = res.data.id setMessage([...messages, res.data]); setNewMessage(""); socket.current.emit('sendMessage', message); @@ -220,7 +224,7 @@ function Chats(){ const [friend, setFriend] = useState(""); - const [modalOpen, setModalOpen] = useState(false); + // const [modalOpen, setModalOpen] = useState(false); const [addFriend, setAddFriend] = useState(false); const [block, setBlock] = useState(false); @@ -228,8 +232,28 @@ function Chats(){ const [showBlockAlert, setShowBlockAlert] = useState(false); const [setting, setSetting] = useState(false); - const close = () => setModalOpen(false); - const open = () => setModalOpen(true); + + const [newGameModalOpen, setNewGameModalOpen] = useState(false); + const [newConversationModalOpen, setNewConversationModalOpen] = useState(false); + + const openNewGameModal = () => { + setNewGameModalOpen(true); + }; + + const closeNewGameModal = () => { + setNewGameModalOpen(false); + }; + + const openNewConversationModal = () => { + setNewConversationModalOpen(true); + }; + + const closeNewConversationModal = () => { + setNewConversationModalOpen(false); + }; + + // const close = () => setModalOpen(false); + // const open = () => setModalOpen(true); // const closeAddFriend = () => setAddFriend(false); // const closeBlock = () => setBlock(false); const closeSetting = () => setSetting(false); @@ -404,17 +428,36 @@ function Chats(){
- - (modalOpen ? close() : open())} - > - - New Conversation - - {modalOpen && } + + + + New Game + + {newGameModalOpen && } + + + + + + New Conversation + + {newConversationModalOpen && ( + + )} + + + + {/* {partyInvite.map((c) => { + return ( + + )}) + } */} + + {partyInvite.map( i =>( + + ))} - {conversations.map((c, index ) => { return (
{messages.map(m=>( - + ))}
{/* */} diff --git a/containers/react/src/components/Messages/GameModal.tsx b/containers/react/src/components/Messages/GameModal.tsx new file mode 100644 index 00000000..f05f2ffd --- /dev/null +++ b/containers/react/src/components/Messages/GameModal.tsx @@ -0,0 +1,142 @@ +import { motion } from "framer-motion"; +import Backdrop from "../Sidebar/Backdrop.tsx"; +import '../../styles/Messages.css'; +import { useState, useEffect } from "react"; +import { GrAdd } from "react-icons/gr"; +import { Link } from "react-router-dom"; +import api from "../../script/axiosApi.tsx"; +import React from "react"; +// import { useNavigate } from "react-router-dom"; + +const dropIn = { + hidden: { y: "-100vh", opacity: 0 }, + visible: { + y: "0", + opacity: 1, + transition: { + duration: 0.3, + type: "spring", + damping: 100, + stiffness: 500, + }, + }, + exit: { y: "100vh", opacity: 0 }, +}; + +const GameModal = ({ handleClose }) => { + const [users, setUsers] = useState([]); + const [selectedUser, setSelectedUser] = useState(''); + const [convs, setConvs] = useState([]); + const [channel, setChannel] = useState(''); + +// const history = useNavigate(); + + useEffect(() => { + const fetchData = async () => { + try { + const tmpUsers = await api.get("/users"); + const tmpConvs = await api.get("/convs"); + setUsers(tmpUsers.data); + setConvs(tmpConvs.data); + } catch (err) { + console.log(err); + } + }; + fetchData(); + }, []); + + const handleUserChange = (event) => { + setSelectedUser(event.target.value); + }; + + const joinChannel = async () => { + try { + await api.post("/join", { convId: channel }); + } catch (err) { + console.log(err); + } + }; + + const handleCheckButtonClick = () => { + // Perform your check action here + console.log("Checking user:", selectedUser); + }; + + const handleButtonClick = () => { + // let path = `play?`; + let path = `http://` + process.env.REACT_APP_BASE_URL + `/pong/play?`; + + const superpowerCheckbox = document.querySelector('input[value="superpower"]'); + if (superpowerCheckbox.checked) { + path += 'superpower=true&'; + } + + const obstacleCheckbox = document.querySelector('input[value="obstacle"]'); + if (obstacleCheckbox.checked) { + path += 'obstacle=true&'; + } + + const speedCheckbox = document.querySelector('input[value="speed"]'); + if (speedCheckbox.checked) { + path += 'speed=true&'; + } + + if (selectedUser.length > 0) + path += 'username=' + selectedUser;//important here + + // Remove the trailing '&' character + // path = path.slice(0, -1); + // console.log(path) + + // console.log("path= ", path) + // history(path, { replace: true }); + // window.location.replace(path); + window.history.pushState({}, null, path); + window.location.reload(false); + + // history(path); + }; + + return ( + + e.stopPropagation()} + className="modal" + variant={dropIn} + initial="hidden" + animate="visible" + exit="exit" + > +
+ +
+ +
+ {/* */} +
+

Super Power

+

Obstacle

+

Faster and Faster

+
+ + +
+ + {/*
+ +
*/} +
+
+ ); +}; + +export default GameModal; diff --git a/containers/react/src/components/Messages/Message.tsx b/containers/react/src/components/Messages/Message.tsx index 97d73e20..fb1f6b3c 100644 --- a/containers/react/src/components/Messages/Message.tsx +++ b/containers/react/src/components/Messages/Message.tsx @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* Message.jsx :+: :+: :+: */ +/* Message.tsx :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/01 18:24:46 by apommier #+# #+# */ -/* Updated: 2023/06/12 17:05:08 by apommier ### ########.fr */ +/* Updated: 2023/06/19 11:45:54 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,6 +17,7 @@ import DefaultPicture from '../../assets/profile.jpg' // import { useRef } from "react"; // import { useEffect } from "react"; import '../../styles/Messages.css' +import React from "react"; const MeStyleP = styled.p` background-color: #5843e4; @@ -29,6 +30,10 @@ const MeStyleP = styled.p` function MessageMe({message, own}){ const [profilePicture, setProfilePicture] = useState(''); + const [sender, setSender] = useState(); + const [conv, setConv] = useState(); + + const [user, setUser] = useState(); const scrollRef = useRef(); useEffect(() => { @@ -39,9 +44,16 @@ function MessageMe({message, own}){ const fetchProfilePicture = async () => { try { // const user = await api.get("/profile"); + const tmpSender = await api.post("/user", {username: message.sender}) + const tmpConv = await api.post("/convId", {convId: message.convId}) + // const tmpSender = await api.post("/user", {username: message.sender}) + const tmpUser = await api.get("/profile") const pic = await api.post("/getPicture", {username: message.sender}) // console.log(`user naem profile pic222= ${currentUser.username}`) // console.log(` profile pic222= ${pic.data}`) + setConv(tmpConv.data); + setUser(tmpUser.data); + setSender(tmpSender.data); setProfilePicture(pic.data); } catch (error) { console.error('Error fetching profile picture:', error); @@ -50,23 +62,45 @@ function MessageMe({message, own}){ fetchProfilePicture(); }, []) + const handleButtonClick = () => { + if (!sender) + return; + let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${sender.username}`; + // console.log("path= ", path) + // history(path, { replace: true }); + // window.location.replace(path); + window.history.pushState({}, null, path); + window.location.reload(false); + }; + + if (!user || !sender || !conv) + return ; + // console.log("result includes=", conv.banned.includes(user.username)) + // console.log("result includes=", conv.blocked.includes(user.username)) + if (user.blocked && user.blocked.includes(message.sender)) + return ; + else if (conv.banned && conv.banned.includes(user.username)) + return ; + // if (user.blocked.includes(message.sender))/ + return (
- {/* profile - */} {profilePicture ? ( - + handleButtonClick()} src={`data:image/jpeg;base64,${profilePicture}`} /> ) : ( - Default Profile Picture + handleButtonClick()} src={DefaultPicture} alt="Default Profile Picture" /> )}
{/*
{message.senderNickname}
*/} -
{message.sender}
+ {sender ? ( +
{sender.nickname}
+ ): ""}
{message.text}
+ ) } diff --git a/containers/react/src/components/Messages/Modal.tsx b/containers/react/src/components/Messages/Modal.tsx index deda5cae..aceb20a9 100644 --- a/containers/react/src/components/Messages/Modal.tsx +++ b/containers/react/src/components/Messages/Modal.tsx @@ -147,7 +147,7 @@ const Modal = ({handleClose}) => { > {convs.map((conv) => ( - !(!conv.group || conv.private || (conv.banned && conv.banned.includes(channel)) || (conv.members && conv.members.includes(user.username))) && ( + !(!conv.group || conv.private || (conv.banned && conv.banned.includes(user.username)) || (conv.members && conv.members.includes(user.username))) && ( @@ -161,30 +161,6 @@ const Modal = ({handleClose}) => {
- {/* {selectTags.map((selectTag) => ( -
- -
- ))} */} - - - - {/*
- -
*/} - diff --git a/containers/react/src/components/Messages/ModalSetting.tsx b/containers/react/src/components/Messages/ModalSetting.tsx index cdb83cd1..1e73932e 100644 --- a/containers/react/src/components/Messages/ModalSetting.tsx +++ b/containers/react/src/components/Messages/ModalSetting.tsx @@ -6,6 +6,7 @@ import { useState, useEffect } from "react"; import { GrAdd } from "react-icons/gr"; import { Link } from "react-router-dom"; import api from "../../script/axiosApi.tsx"; +import React from "react"; const dropIn = { @@ -114,6 +115,9 @@ const ModalSetting = ({handleClose, convId}) => { const handleBan = () => { // console.log("ban option= ", selectedUser) try{ + // console.log("user select=", selectedUser.length) + if (!selectedUser.length) + return ; api.post("/ban", {convId: convId, username: selectedUser}) } catch(err) { console.log(err); @@ -122,6 +126,8 @@ const ModalSetting = ({handleClose, convId}) => { }; const handleAdmin = () => { + if (!selectedUser.length) + return ; try{ api.post("/admin", {convId: convId, username: selectedUser}) } catch(err) { @@ -131,6 +137,8 @@ const ModalSetting = ({handleClose, convId}) => { }; const handleMute = () => { + if (!selectedUser.length) + return ; try{ api.post("/mute", {convId: convId, username: selectedUser}) } catch(err) { @@ -162,7 +170,7 @@ const ModalSetting = ({handleClose, convId}) => { {/* First selection */}
-

Private

+

Private

Password

diff --git a/containers/react/src/components/Social/FriendRequest.tsx~HEAD b/containers/react/src/components/Messages/PartyInvite.tsx similarity index 59% rename from containers/react/src/components/Social/FriendRequest.tsx~HEAD rename to containers/react/src/components/Messages/PartyInvite.tsx index 4fffff6e..e73bab4e 100644 --- a/containers/react/src/components/Social/FriendRequest.tsx~HEAD +++ b/containers/react/src/components/Messages/PartyInvite.tsx @@ -1,3 +1,15 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* PartyInvite.tsx :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: apommier +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/06/19 16:44:29 by apommier #+# #+# */ +/* Updated: 2023/06/19 17:26:22 by apommier ### ########.fr */ +/* */ +/* ************************************************************************** */ + import { useEffect, useState } from "react"; import api from '../../script/axiosApi.tsx'; @@ -5,6 +17,7 @@ import DefaultPicture from '../../assets/profile.jpg' import styled from "styled-components"; import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx"; +import React from "react"; const UserChat = styled.div ` padding: 5px; @@ -25,7 +38,7 @@ const SideP = styled.p` margin-left: 15px; ` -export default function Friend({currentUser}) +export default function PartyInvite({currentInvite}) { const [profilePicture, setProfilePicture] = useState(''); const [request, setRequest] = useState(''); //user who invite @@ -37,11 +50,11 @@ export default function Friend({currentUser}) try { // const user = await api.get("/profile");\ // const tmpUser = await api.get("/profile") - const pic = await api.post("/getPicture", {username: currentUser.username}) - const tmpRequest = await api.post("/user", {username: currentUser.username}) + const pic = await api.post("/getPicture", {username: currentInvite.username}) + const tmpRequest = await api.post("/user", {username: currentInvite.username}) // setUser(tmpUser.data); setRequest(tmpRequest.data); - // console.log(`user naem profile pic222= ${currentUser.username}`) + // console.log(`user naem profile pic222= ${currentInvite.username}`) // console.log(` profile pic222= ${pic.data}`) setProfilePicture(pic.data); } catch (error) { @@ -60,10 +73,20 @@ export default function Friend({currentUser}) window.location.reload(false); }; + + + const Accept = async (request) => { try{ - await api.post("/friend", {username: request.username}) - setClickEvent(true); + //call canvas ?? + // await api.post("/friend", {username: request.username}) + await api.post("/deleteInvite", {username: request.username}) + let path = `http://` + process.env.REACT_APP_BASE_URL + `/pong/play?` + path += 'username=' + request.username; + path += '&gameId=' + currentInvite.gameId; + // setClickEvent(true); + window.history.pushState({}, null, path); + window.location.reload(false); } catch(err) { console.log(err); } @@ -73,7 +96,8 @@ export default function Friend({currentUser}) const Refuse = async (request) => { try{ - await api.post("/refuseInvite", {username: request.username}) + await api.post("/deleteInvite", {username: request.username}) + // await api.post("/refuseInvite", {username: request.username}) setClickEvent(true); } catch(err) { console.log(err); @@ -95,12 +119,11 @@ export default function Friend({currentUser}) Default Profile Picture )}
- handleButtonClick(currentUser)}>{currentUser.nickname} + handleButtonClick(currentInvite)}>{request.nickname} Accept(request)} color={'green'}/> Refuse(request)} color={'red'}/>
) -} - \ No newline at end of file +} \ No newline at end of file diff --git a/containers/react/src/components/Profile/EditName.tsx b/containers/react/src/components/Profile/EditName.tsx index be339f14..6b232b9c 100644 --- a/containers/react/src/components/Profile/EditName.tsx +++ b/containers/react/src/components/Profile/EditName.tsx @@ -33,6 +33,7 @@ const ModalEdit = ( handleClose ) => { const handler = e => { setNickname(e.target.value); + console.log("testeeeee") const postNickname = async ()=>{ try{ await api.post("/nickname", {nickname: nickname}) @@ -45,6 +46,22 @@ const ModalEdit = ( handleClose ) => { }; postNickname(); } + + const handlePostNickname = async () => + { + console.log("nickname=" ,nickname) + try{ + await api.post("/nickname", {nickname: nickname}) + window.location.reload(false); + // setUser(tmpUser.data); + // setIsLoading(false) + } + catch(err){ + console.log(err); + } + } + + // function handleClose(){ // //do nothing // } @@ -56,10 +73,11 @@ const ModalEdit = ( handleClose ) => { animate="visible" exit="exit">

Type your new name

- -
-
{UserProfile.UserName = nickname;}}> - change + +
+
handlePostNickname()}> + change + {/* change */}
diff --git a/containers/react/src/components/Sidebar/SidebarData.tsx b/containers/react/src/components/Sidebar/SidebarData.tsx index b0c242f4..f3812ac6 100644 --- a/containers/react/src/components/Sidebar/SidebarData.tsx +++ b/containers/react/src/components/Sidebar/SidebarData.tsx @@ -26,7 +26,7 @@ export const SidebarData = [ cName: 'nav-text' }, { - title: 'Social', + title: 'Friend', path: '/social', icon: , cName: 'nav-text' diff --git a/containers/react/src/components/Social/Friend.tsx~HEAD b/containers/react/src/components/Social/Friend.tsx~HEAD deleted file mode 100644 index 0c6c894d..00000000 --- a/containers/react/src/components/Social/Friend.tsx~HEAD +++ /dev/null @@ -1,111 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* Friend.jsx :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: apommier +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2023/06/09 08:18:58 by apommier #+# #+# */ -/* Updated: 2023/06/15 19:05:14 by apommier ### ########.fr */ -/* */ -/* ************************************************************************** */ - -import { useEffect, useState } from "react"; -import api from '../../script/axiosApi.tsx'; -import DefaultPicture from '../../assets/profile.jpg' -import styled from "styled-components"; - -import { RxCircle } from "react-icons/rx"; -import { CgFontSpacing } from "react-icons/cg"; - -const UserChat = styled.div ` - padding: 5px; - display: flex; - align-items: center; - gap: 5px; - color: white; - cursor: pointer; - - &:hover{ - background-color: #3e3c61; - } -` - -const SideP = styled.p` - font-size: 14px; - color: lightgray; - margin-left: 15px; -` - -export default function Friend({currentUser}) -{ - const [profilePicture, setProfilePicture] = useState(''); - - useEffect(() => { - const fetchProfilePicture = async () => { - try { - // const user = await api.get("/profile"); - const pic = await api.post("/getPicture", {username: currentUser.username}) - // console.log(`user naem profile pic222= ${currentUser.username}`) - // console.log(` profile pic222= ${pic.data}`) - setProfilePicture(pic.data); - } catch (error) { - console.error('Error fetching profile picture:', error); - } - }; - - fetchProfilePicture(); - }) - - function getStatus(friend) - { - let status = friend.status - console.log(`status= ${status}`) - let statusColor; - - if (status === 0) - statusColor = 'grey'; - else if (status === 1) - statusColor = 'green'; - else if (status === 2) - statusColor = 'blue'; - return statusColor; - } - - const handleSpectate = (user) => { - //socket connection and add to party with one with username - console.log(`spectate hehe`) - console.log(`user= ${user}`) - }; - - const handleButtonClick = (user) => { - let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`; - console.log("path= ", path) - // history(path, { replace: true }); - // window.location.replace(path); - window.history.pushState({}, null, path); - window.location.reload(false); - }; - - return ( - - {profilePicture ? ( - - ) : ( - Default Profile Picture - )} -
- handleButtonClick(currentUser)}>{currentUser.nickname} - - - {getStatus(currentUser) !== 'blue' ? ( - <> - ) : ( - - )} -
-
- ) -} - - diff --git a/containers/react/src/components/Social/FriendRequest.tsx b/containers/react/src/components/Social/FriendRequest.tsx index 4fffff6e..cf9af1da 100644 --- a/containers/react/src/components/Social/FriendRequest.tsx +++ b/containers/react/src/components/Social/FriendRequest.tsx @@ -5,6 +5,7 @@ import DefaultPicture from '../../assets/profile.jpg' import styled from "styled-components"; import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx"; +import React from "react"; const UserChat = styled.div ` padding: 5px; diff --git a/containers/react/src/pages/Field.tsx b/containers/react/src/pages/Field.tsx index a8505d82..86de3807 100644 --- a/containers/react/src/pages/Field.tsx +++ b/containers/react/src/pages/Field.tsx @@ -5,6 +5,7 @@ import queryString from 'query-string'; import '../styles/field.css'; import { useParams } from "react-router-dom"; +import React from 'react'; // import { withRouter } from 'react-router-dom'; @@ -16,7 +17,8 @@ function Field() console.log("launch canva hehe") let Modifiers = 0; - + let info; + if (queryParams.superpower === 'true') { Modifiers += 1; } @@ -28,15 +30,23 @@ function Field() if (queryParams.speed === 'true') { Modifiers += 4; } - // console.log(`modifiers= ${Modifiers}`) - // DrawCanvas(Modifiers); - // return () => { - // console.log("000000000000000000000000000000000") - // // socketRef.current.disconnect(); - // }; + + info = { + privateParty: false, + } + if (queryParams.username) + { + console.log("user= ", queryParams.username) + info = { + privateParty: true, + username: queryParams.username, + } + if (queryParams.gameId) + info.gameId = queryParams.gameId + console.log("info of param vefore canvas=", info) + } - // console.log(`modifiers= ${Modifiers}`) - const cleanup = DrawCanvas(Modifiers); + const cleanup = DrawCanvas(Modifiers, info); return () => { console.log("Cleanup"); diff --git a/containers/react/src/pages/Home.tsx b/containers/react/src/pages/Home.tsx index 5e557fc8..0f5f40db 100644 --- a/containers/react/src/pages/Home.tsx +++ b/containers/react/src/pages/Home.tsx @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* Home.jsx :+: :+: :+: */ +/* Home.tsx :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/09 08:19:04 by apommier #+# #+# */ -/* Updated: 2023/06/09 08:19:05 by apommier ### ########.fr */ +/* Updated: 2023/06/19 20:27:00 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -139,10 +139,11 @@ function Profile () { -
- - -
+
+ + + +
) : ( <> diff --git a/containers/react/src/pages/Login42.tsx b/containers/react/src/pages/Login42.tsx index c3bfbc8f..e69c9e8e 100644 --- a/containers/react/src/pages/Login42.tsx +++ b/containers/react/src/pages/Login42.tsx @@ -15,12 +15,15 @@ function Login42() const data = { grant_type: 'authorization_code', - client_id: 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41', - client_secret: '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', + // 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 diff --git a/containers/react/src/pages/canvas.tsx b/containers/react/src/pages/canvas.tsx index 6ff0f0a3..b02274ae 100644 --- a/containers/react/src/pages/canvas.tsx +++ b/containers/react/src/pages/canvas.tsx @@ -8,9 +8,7 @@ import io from 'socket.io-client'; // const socket = io('http://86.209.110.20:4000'); // const socket = io('http://172.29.113.91:4000'); -function DrawCanvas(option) { - - +function DrawCanvas(option: number, gameParam) { console.log(`option= ${option}`); const superpowerModifier = option & 1; // Retrieves the superpower modifier @@ -26,6 +24,26 @@ function DrawCanvas(option) { // const socketRef = useRef(null); // socketRef.current = io('http://localhost:4000'); const socket = io('http://' + process.env.REACT_APP_BASE_URL + ':4000'); + + function launchGame() + { + if (!gameParam.privateParty) + { + console.log("laucnh matchmaking") + matchmaking(); + } + else if (!gameParam.gameId) + { + console.log("laucnh private") + privateParty(); + } + else + { + console.log("join private") + joinPrivateParty(); + } + } + // const socket = socketRef.current console.log("start function"); @@ -45,7 +63,7 @@ function DrawCanvas(option) { //======================================================================================================== //======================================================================================================== -// Var Declaration +// Var Declaration //======================================================================================================== //======================================================================================================== @@ -102,7 +120,136 @@ function DrawCanvas(option) { //======================================================================================================== //======================================================================================================== -// Socket handler +// Socket ON +//======================================================================================================== +//======================================================================================================== + +socket.on('pong:win', async () => { + myScore = maxScore; + 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") + await api.post('/status', {status: 1}); + console.log("after request2") + //disconnect ? + running = false; + socket.emit('pong:disconnect', {id: myId}); + console.log("before reload") + window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong"); + // window.location.reload(false); + return ; + // console.log("send all ?? win"); + +}); + +socket.on('pong:privateId', async (data) => { + console.log("private id = ", data) + try{ + await api.post("/partyInvite", {username: gameParam.username, gameId: data}); + } catch(err) { + console.log(err) + } +}); + +socket.on('pong:gameId', async (data) => { + console.log("gameId received"); + gameId = data; + + try { + let response = await api.get('/profile'); + const myName = response.data.username; + response = await api.get('/rank'); + await api.post('/status', {status: 2}); + opRank = response.data + console.log(`rank= ${opRank}`); + console.log(`myname= ${myName}`); + + const info = { + id: myId, + name: myName, + gameId: gameId, + rank: opRank, + }; + + console.log("emit to name"); + socket.emit('pong:name', info); + } catch (error) { + console.log(error); + // Handle error here + return; + } + }); + +socket.on('pong:name', (data) => { + opName = data; + console.log(`opponent Name= ${opName}`) +}); + +socket.on('connect', () => { + console.log('Connected to NestJS server'); +}); + +socket.on('pong:clientId', (data) => { + console.log("receive id") + myId = data; + console.log(`id is= ${myId}`) + launchGame(); +}); + +socket.on('pong:info', (data) => { + oPaddleY = (data.paddleY / data.height) * canvas.height//canvas.height - data.ballY; + ballX = canvas.width - (data.ballX * (canvas.width / data.width));//- data.ballX; + ballY = ((data.ballY / data.height) * canvas.height)//canvas.height - data.ballY; + + vX = -data.vX; + vY = data.vY; +}); + + +socket.on('pong:paddle', (data) => { + console.log("paddle info receive") + oPaddleY = (data.paddleY / data.height) * canvas.height +}); + +socket.on('pong:power', (data) => { + console.log("paddle info receive") + + oPaddleY = 0; + opPaddleHeight = canvas.height; + + setTimeout(() => { + // code à exécuter après 5 secondes + opPaddleHeight = canvas.height * 0.25; + oPaddleY = canvas.height / 2 - paddleHeight / 2; + console.log('Cinq secondes se sont écoulées.'); + }, 5000); + // oPaddleY = (data.paddleY / data.height) * canvas.height +}); + +socket.on('pong:point', (data) => { + // hisScore += 1; + console.log("gain point"); + // if (vX != 0) + // { + // console.log("up point"); + myScore = data.point; + // } + vX = 0; + vY = 0; + ballX = canvas.width / 2; + ballY = canvas.height / 2; +}); + +//======================================================================================================== +//======================================================================================================== +// Socket EMIT //======================================================================================================== //======================================================================================================== @@ -116,106 +263,26 @@ function DrawCanvas(option) { socket.emit('pong:matchmaking', info); } - // socket.on('pong:gameId', (data) => { - // console.log("gameId received") - // gameId = data; - // // api.get('/profile'); - - // let myName; - - // api.get('/profile').then((data) => { - // // Faire quelque chose avec les données - // console.log(data); - // myName = data.data.username; - // console.log(`myname= ${myName}`); - // }).catch((error) => { - // console.log(error); - // // exit() ; - // return; - // }); - - // const info = { - // id: myId, - // name: myName, - // gameId: gameId, - // }; - // console.log("emit to name") - // socket.emit('pong:name', info); - // }); - - socket.on('pong:gameId', async (data) => { - console.log("gameId received"); - gameId = data; - - try { - let response = await api.get('/profile'); - const myName = response.data.username; - response = await api.get('/rank'); - await api.post('/status', {status: 2}); - opRank = response.data - console.log(`rank= ${opRank}`); - console.log(`myname= ${myName}`); - - const info = { + function privateParty() + { + console.log(`id private party= ${myId}`) + const info = { id: myId, - name: myName, - gameId: gameId, - rank: opRank, - }; - - console.log("emit to name"); - socket.emit('pong:name', info); - } catch (error) { - console.log(error); - // Handle error here - return; - } - }); + option: option, + }; + socket.emit('pong:privateParty', info); + } - socket.on('pong:name', (data) => { - opName = data; - console.log(`opponent Name= ${opName}`) - }); - - socket.on('connect', () => { - console.log('Connected to NestJS server'); - }); - - socket.on('pong:clientId', (data) => { - console.log("receive id") - myId = data; - console.log(`id is= ${myId}`) - }); - - socket.on('pong:info', (data) => { - oPaddleY = (data.paddleY / data.height) * canvas.height//canvas.height - data.ballY; - ballX = canvas.width - (data.ballX * (canvas.width / data.width));//- data.ballX; - ballY = ((data.ballY / data.height) * canvas.height)//canvas.height - data.ballY; - - vX = -data.vX; - vY = data.vY; - }); - - - socket.on('pong:paddle', (data) => { - console.log("paddle info receive") - oPaddleY = (data.paddleY / data.height) * canvas.height - }); - - socket.on('pong:power', (data) => { - console.log("paddle info receive") - - oPaddleY = 0; - opPaddleHeight = canvas.height; - - setTimeout(() => { - // code à exécuter après 5 secondes - opPaddleHeight = canvas.height * 0.25; - oPaddleY = canvas.height / 2 - paddleHeight / 2; - console.log('Cinq secondes se sont écoulées.'); - }, 5000); - // oPaddleY = (data.paddleY / data.height) * canvas.height - }); + function joinPrivateParty() + { + console.log(`id private party= ${myId}`) + const info = { + id: myId, + gameId: gameParam.gameId, + option: option, + }; + socket.emit('pong:joinParty', info); + } function send_info() { @@ -248,20 +315,6 @@ function DrawCanvas(option) { socket.emit('pong:point', info); } - socket.on('pong:point', (data) => { - // hisScore += 1; - console.log("gain point"); - // if (vX != 0) - // { - // console.log("up point"); - myScore = data.point; - // } - vX = 0; - vY = 0; - ballX = canvas.width / 2; - ballY = canvas.height / 2; - }); - function send_paddle_info() { if (gameId === 0) @@ -307,7 +360,7 @@ function DrawCanvas(option) { //======================================================================================================== //======================================================================================================== -// Drawer +// Drawer //======================================================================================================== //======================================================================================================== @@ -348,28 +401,50 @@ function DrawCanvas(option) { //======================================================================================================== //======================================================================================================== -// Loop +// Loop //======================================================================================================== //======================================================================================================== -matchmaking(); + // while (!gameId) // ; // Define a function to stop the drawing process - const stopDrawCanvas = () => { + const stopDrawCanvas = async () => { running = false; + + console.log("stopDrawCanvas 1") + + if (gameParam.privateParty && !gameId) //delete invite + { + console.log("stopDrawCanvas2") + try{ + // const info = { + // id: myId, + // option: option, + // }; + + await api.post("deleteInvite", {username: gameParam.username}) + } + catch (err){ + console.log(err) + } + } + socket.emit('pong:disconnect', {id: myId}); + window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong"); + // window.location.reload(false); // Perform any necessary cleanup tasks // ... }; -function draw(timestamp) +async function draw(timestamp) { - console.log("turning"); + console.log("turning, running= ", running); if (!running) return ; if (gameId === 0 ) { + // console.log("nogameid score= ", myScore); requestAnimationFrame(draw); return ; } @@ -383,17 +458,22 @@ function draw(timestamp) }; if (myScore === maxScore) { - api.post('/win', data); - api.post('/status', {status: 1}); - console.log("send win"); + await api.post('/win', data); + await api.post('/status', {status: 1}); + //disconnect ? + socket.emit('pong:disconnect', {id: myId}); + + console.log("send all ?? win"); } else { - api.post('/loss', data); - api.post('/status', {status: 1}); + // await api.post('/loss', data); + // await api.post('/status', {status: 1}); + //disconnect ? console.log("send loose"); } window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong"); + // window.location.reload(false); return ; } @@ -415,7 +495,7 @@ function draw(timestamp) //======================================================================================================== //======================================================================================================== -// Logical Part +// Logical Part //======================================================================================================== //======================================================================================================== @@ -521,7 +601,7 @@ function draw(timestamp) //======================================================================================================== //======================================================================================================== -// Listener +// Key/Mouse/Finger Listener //======================================================================================================== //======================================================================================================== diff --git a/containers/react/src/styles/Profile.css b/containers/react/src/styles/Profile.css index 77843ff8..aa1a90fd 100644 --- a/containers/react/src/styles/Profile.css +++ b/containers/react/src/styles/Profile.css @@ -1,3 +1,68 @@ + /* Container style */ + .file-upload-container { + + margin-left: 2rem; + font-size: 1.7rem; + /* background: #5843e4; */ + /* color:#f5f5f5; */ + margin: 0 16px; + text-decoration: none; + padding: 10px 16px; + border-radius: 20px; + + display: flex; + align-items: center; + gap: 10px; + } + + /* File input style */ + .file-input { + /* background: #5843e4; */ + /* color:#f5f5f5; */ + display: none; /* Hide the default file input */ + } + + .file-label { + padding: 8px 12px; + background-color: #f2f2f2; + color: #555; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.3s ease; + } + + .file-label:hover { + background-color: #e0e0e0; + } + + /* Button style */ + .upload-button { + padding: 8px 12px; + background-color: #5843e4; + color: #fff; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.3s ease; + } + + .upload-button:hover { + background-color: #0056b3; + } + + + + + + + + + + + + + + .page { text-align: center; /* height: 50vh; */ From b53151ac5fe6651e0edbf0387c38626bcabaccc6 Mon Sep 17 00:00:00 2001 From: kinou-p Date: Tue, 20 Jun 2023 15:37:05 +0200 Subject: [PATCH 04/13] fix all error tsx add tsconfig and some type in interface.tsx --- containers/react/assets.d.ts | 2 + containers/react/interfaces.tsx | 48 ++++++++ .../react/src/components/Alert/GreenAlert.tsx | 12 +- .../react/src/components/Alert/RedAlert.tsx | 12 +- .../src/components/Alert/YellowAlert.tsx | 12 +- .../react/src/components/AnimatedRoute.tsx | 10 +- .../react/src/components/Game/PlayButton.tsx | 13 +- containers/react/src/components/Game/Rank.tsx | 13 +- .../react/src/components/Game/Ranking.tsx | 3 +- containers/react/src/components/Header.tsx | 2 +- .../react/src/components/Messages/Chats.tsx | 72 ++++++++---- .../src/components/Messages/GameModal.tsx | 43 ++++--- .../react/src/components/Messages/Input.tsx | 1 + .../react/src/components/Messages/Message.tsx | 30 +++-- .../src/components/Messages/MessageMe.tsx | 3 +- .../src/components/Messages/MessageYou.tsx | 2 +- .../react/src/components/Messages/Modal.tsx | 2 +- .../src/components/Messages/ModalSetting.tsx | 27 +++-- .../src/components/Messages/PartyInvite.tsx | 33 ++++-- .../react/src/components/Profile/EditName.tsx | 2 +- .../react/src/components/Profile/Logout.tsx | 6 +- .../react/src/components/Profile/Win_Loss.tsx | 7 +- .../react/src/components/Sidebar/Backdrop.tsx | 8 +- .../react/src/components/Sidebar/Modal.tsx | 7 +- .../react/src/components/Social/Friend.tsx | 21 ++-- .../src/components/Social/FriendRequest.tsx | 22 ++-- .../react/src/components/Social/Social.tsx | 8 +- containers/react/src/pages/Field.tsx | 21 ++-- containers/react/src/pages/Head.tsx | 4 +- containers/react/src/pages/Home.tsx | 108 ++++++++++++----- containers/react/src/pages/Login42.tsx | 3 +- containers/react/src/pages/Messages.tsx | 2 +- containers/react/src/pages/NewLogin.tsx | 1 + containers/react/src/pages/QrCode.tsx | 24 ++-- containers/react/src/pages/canvas.tsx | 86 +++++++++----- containers/react/src/script/tokenSuccess.tsx | 8 +- containers/react/src/styles/Messages.css | 13 +- containers/react/src/styles/Profile.css | 6 +- containers/react/src/styles/old.css | 5 - containers/react/tsconfig.json | 111 ++++++++++++++++++ containers/test | 2 - 41 files changed, 585 insertions(+), 230 deletions(-) create mode 100644 containers/react/assets.d.ts create mode 100644 containers/react/interfaces.tsx create mode 100644 containers/react/tsconfig.json delete mode 100644 containers/test diff --git a/containers/react/assets.d.ts b/containers/react/assets.d.ts new file mode 100644 index 00000000..cb5e5ab2 --- /dev/null +++ b/containers/react/assets.d.ts @@ -0,0 +1,2 @@ +declare module '*.jpg'; +declare module 'styled-components' \ No newline at end of file diff --git a/containers/react/interfaces.tsx b/containers/react/interfaces.tsx new file mode 100644 index 00000000..1faa97ec --- /dev/null +++ b/containers/react/interfaces.tsx @@ -0,0 +1,48 @@ +export interface User { + id: number; + otp_enabled: boolean; + otp_verified: boolean; + otp_base32: string; + nickname: string; + username: string; + photo: Buffer; + password: string; + win: number; + loss: number; + rank: number; + status: number; + userId: number; + friendRequest: string[]; + partyInvite: Record[]; + friends: string[]; + blocked: string[]; + } + +export interface Conv { + id: number; + members?: string[]; + name: string + group: boolean + private: boolean + banned?: string[]; + muted?: string[]; + admin?: string[]; + owner?: string; + password?: string; + } + +export interface Message { + id: number; + convId: number; + sender: string; + text: string; + createdAt?: Date; + } + +export interface Matchlog { + id: number; + opponent: string; + myScore: number; + opScore: number; + parent: User; + } \ No newline at end of file diff --git a/containers/react/src/components/Alert/GreenAlert.tsx b/containers/react/src/components/Alert/GreenAlert.tsx index 9193bcd0..11832c45 100644 --- a/containers/react/src/components/Alert/GreenAlert.tsx +++ b/containers/react/src/components/Alert/GreenAlert.tsx @@ -2,6 +2,7 @@ import Backdrop from "../Sidebar/Backdrop.tsx" import { motion } from 'framer-motion' import { AiOutlineCheckCircle } from "react-icons/ai"; import '../../styles/Messages.css' +import React from "react"; const dropIn = { @@ -16,14 +17,19 @@ const dropIn = { }, }; -function GreenAlert ({handleClose, text}){ +interface AlertProps { + handleClose: Function, + text: string + } + +function GreenAlert ({handleClose, text}: AlertProps){ return( - + e.stopPropagation()} className="greenAlert" - variant={dropIn} + // variant={dropIn} initial="hidden" animate="visible" exit="exit" diff --git a/containers/react/src/components/Alert/RedAlert.tsx b/containers/react/src/components/Alert/RedAlert.tsx index 51fae963..9ec3c4bc 100644 --- a/containers/react/src/components/Alert/RedAlert.tsx +++ b/containers/react/src/components/Alert/RedAlert.tsx @@ -2,6 +2,7 @@ import Backdrop from "../Sidebar/Backdrop.tsx" import { motion } from 'framer-motion' import { BiErrorCircle } from "react-icons/bi"; import '../../styles/Messages.css' +import React from "react"; const dropIn = { @@ -16,13 +17,18 @@ const dropIn = { }, }; -function RedAlert ({handleClose, text}) { +interface AlertProps { + handleClose: Function, + text: string + } + +function RedAlert ({handleClose, text}: AlertProps) { return( - + e.stopPropagation()} className="redAlert" - variant={dropIn} + // variant={dropIn} initial="hidden" animate="visible" exit="exit" diff --git a/containers/react/src/components/Alert/YellowAlert.tsx b/containers/react/src/components/Alert/YellowAlert.tsx index 0627e676..1537dd54 100644 --- a/containers/react/src/components/Alert/YellowAlert.tsx +++ b/containers/react/src/components/Alert/YellowAlert.tsx @@ -2,6 +2,7 @@ import Backdrop from "../Sidebar/Backdrop.tsx" import { motion } from 'framer-motion' import { GrTrophy } from "react-icons/gr"; import '../../styles/Messages.css' +import React from "react"; const dropIn = { hidden: { @@ -15,13 +16,18 @@ const dropIn = { }, }; -function YellowAlert ({handleClose, text}) { +interface AlertProps { + handleClose: Function, + text: string + } + +function YellowAlert ({handleClose, text}: AlertProps) { return( - + e.stopPropagation()} className="yellowAlert" - variant={dropIn} + // variant={dropIn} initial="hidden" animate="visible" exit="exit" diff --git a/containers/react/src/components/AnimatedRoute.tsx b/containers/react/src/components/AnimatedRoute.tsx index 5a11edb1..7201aacc 100644 --- a/containers/react/src/components/AnimatedRoute.tsx +++ b/containers/react/src/components/AnimatedRoute.tsx @@ -1,7 +1,7 @@ import React from "react"; import {Routes, Route} from 'react-router-dom'; import Home from "../pages/Home.jsx"; -import PlayButton from "../pages/PlayButton.js"; +import PlayButton from "./Game/PlayButton.tsx"; import Field from "../pages/Field"; import Login42 from "../pages/Login42.js"; import Messages from "../pages/Messages.jsx"; @@ -13,11 +13,11 @@ function AnimatedRoute () { return ( - }/> + }/> }/> - }/> - }/> - }/> + }/> + }/> + }/> ) diff --git a/containers/react/src/components/Game/PlayButton.tsx b/containers/react/src/components/Game/PlayButton.tsx index 04576ec7..7e018a04 100644 --- a/containers/react/src/components/Game/PlayButton.tsx +++ b/containers/react/src/components/Game/PlayButton.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import '../../styles/field.css'; // import { useHistory } from 'react-router-dom'; import { useNavigate } from "react-router-dom"; @@ -13,18 +14,18 @@ function PlayButton() { const handleButtonClick = () => { let path = `play?`; - const superpowerCheckbox = document.querySelector('input[value="superpower"]'); - if (superpowerCheckbox.checked) { + const superpowerCheckbox = document.querySelector('input[value="superpower"]'); + if (superpowerCheckbox && superpowerCheckbox.checked) { path += 'superpower=true&'; } - const obstacleCheckbox = document.querySelector('input[value="obstacle"]'); - if (obstacleCheckbox.checked) { + const obstacleCheckbox = document.querySelector('input[value="obstacle"]'); + if (obstacleCheckbox && obstacleCheckbox.checked) { path += 'obstacle=true&'; } - const speedCheckbox = document.querySelector('input[value="speed"]'); - if (speedCheckbox.checked) { + const speedCheckbox = document.querySelector('input[value="speed"]'); + if (speedCheckbox && speedCheckbox.checked) { path += 'speed=true&'; } diff --git a/containers/react/src/components/Game/Rank.tsx b/containers/react/src/components/Game/Rank.tsx index b65e297d..4523c988 100644 --- a/containers/react/src/components/Game/Rank.tsx +++ b/containers/react/src/components/Game/Rank.tsx @@ -6,7 +6,7 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/09 08:49:24 by apommier #+# #+# */ -/* Updated: 2023/06/19 20:35:39 by apommier ### ########.fr */ +/* Updated: 2023/06/20 13:06:35 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,8 +15,15 @@ import React, { useState, useEffect, useRef } from "react"; // import {Rank} from '../../DataBase/DataRank.js' import DefaultPicture from '../../assets/profile.jpg' import api from '../../script/axiosApi.tsx'; +import {Matchlog, User} from "../../../interfaces.tsx" +// import { Match } from "@testing-library/react"; -function Rank({user, index}){ +interface RankProps { + user: User + index: number +} + +function Rank({user, index}: RankProps){ const [profilePicture, setProfilePicture] = useState(''); @@ -51,7 +58,7 @@ function Rank({user, index}){ {/* */}
-

{user.opponent}

+ {/*

{user.opponent}

*/}
) } diff --git a/containers/react/src/components/Game/Ranking.tsx b/containers/react/src/components/Game/Ranking.tsx index aa564f08..1880abcc 100644 --- a/containers/react/src/components/Game/Ranking.tsx +++ b/containers/react/src/components/Game/Ranking.tsx @@ -3,11 +3,12 @@ import React, { useState, useEffect, useRef } from "react"; import Rank from './Rank.tsx' import defaultpic from '../../assets/profile.jpg' import api from '../../script/axiosApi.tsx'; +import {User} from "../../../interfaces.tsx" function Ranking(){ const [isLoading, setIsLoading] = useState(true); - const [ranking, setRanking] = useState([]); + const [ranking, setRanking] = useState([]); useEffect(()=> { diff --git a/containers/react/src/components/Header.tsx b/containers/react/src/components/Header.tsx index 799d1abf..05ab38db 100644 --- a/containers/react/src/components/Header.tsx +++ b/containers/react/src/components/Header.tsx @@ -62,7 +62,7 @@ function Header() { null}> - {modalOpen && } + {modalOpen && }
); diff --git a/containers/react/src/components/Messages/Chats.tsx b/containers/react/src/components/Messages/Chats.tsx index 9f5015c2..0ada4409 100644 --- a/containers/react/src/components/Messages/Chats.tsx +++ b/containers/react/src/components/Messages/Chats.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect, useRef } from "react"; -import io from 'socket.io-client'; +import io, { Socket } from 'socket.io-client'; import '../../styles/Messages.css' import styled from "styled-components"; import DefaultPic from '../../assets/profile.jpg' @@ -18,13 +18,15 @@ import { MdOutlineGroupAdd } from 'react-icons/md'; import { GrAdd } from 'react-icons/gr'; import { RiListSettingsLine } from 'react-icons/ri' -import { Rank } from "../../DataBase/DataRank"; +// import { Rank } from "../../DataBase/DataRank"; import GreenAlert from "../Alert/GreenAlert.tsx"; import RedAlert from "../Alert/RedAlert.tsx"; import YellowAlert from "../Alert/YellowAlert"; import ModalSetting from "./ModalSetting.tsx"; import PartyInvite from "./PartyInvite.tsx"; +// import {User, Conv, Message} from "../../../interfaces.tsx" +import {User, Conv} from "../../../interfaces.tsx" const TouchDiv = styled.div` margin-left: 10px; @@ -72,25 +74,32 @@ const SideP = styled.p` //======================================================================================================== //======================================================================================================== +interface MessageProps { + id: number; + convId: number; + sender: string; + text: string; + createdAt?: Date; + } function Chats(){ - const [isLoading, setIsLoading] = useState(true); + const [isLoading, setIsLoading] = useState(true); const [conversations, setConversation] = useState([]); const [partyInvite, setPartyInvite] = useState([]); - const [user, setUser] = useState(null); - const [currentChat, setCurrentChat] = useState(false); // false is good? - const [isAdmin, setIsAdmin] = useState(false); // false is good? + const [user, setUser] = useState(); + const [currentChat, setCurrentChat] = useState(); // false is good? + const [isAdmin, setIsAdmin] = useState(false); // false is good? // const [currentChat, setCurrentChat] = useState(false); // false is good? - const [messages, setMessage] = useState([]); + const [messages, setMessage] = useState([]); const [newMessages, setNewMessage] = useState(""); - const [incomingMessage, setIncomingMessage] = useState(""); + const [incomingMessage, setIncomingMessage] = useState(); - let socket; - socket = useRef(); + // let socket: Socket; + const socket = useRef(null); + // socket = useRef( useRef(null)); - useEffect(()=> { const getConv = async ()=>{ @@ -144,7 +153,7 @@ function Chats(){ } } // console.log(`result1 = ${currentChat.id !== incomingMessage.convId}`) - if (currentChat !== null && currentChat.id === incomingMessage.convId) + if (currentChat && incomingMessage && currentChat.id === incomingMessage.convId) { console.log("incoming meaasge=",incomingMessage) // if (user && !user.blocked.find(incomingMessage.sender)) @@ -160,8 +169,10 @@ function Chats(){ useEffect(()=> { const getMessage = async ()=> { + if (!currentChat) + return ; const data = {convId: currentChat.id}; - + try { const res = await api.post('/getMessage', data); setMessage(res.data); @@ -172,15 +183,19 @@ function Chats(){ getMessage(); }, [currentChat]); - const handleSubmit = async (e)=>{ + const handleSubmit = async (e: { preventDefault: () => void; })=>{ e.preventDefault(); // console.log(`e= ${e.key}`) // console.log(`name= ${user.username}`) + // let message; + if (!user || !currentChat) + return ; const message = { sender: user.username, text: newMessages, convId: currentChat.id, - members: null + members: null, + id: null, }; try{ const res = await api.post('/message', message); @@ -189,23 +204,27 @@ function Chats(){ message.id = res.data.id setMessage([...messages, res.data]); setNewMessage(""); - socket.current.emit('sendMessage', message); + if (socket.current) + socket.current.emit('sendMessage', message); } catch(err){ console.log(err) } } - const handleKeyPress = async (e)=>{ + const handleKeyPress = async (e: { key: string; })=> { // console.log(`e in press= ${e.key}`) if (e.key !== "Enter") return ; // console.log(`name= ${user.username}`) + if (!user || !currentChat) + return ; const message = { sender: user.username, text: newMessages, convId: currentChat.id, - members: null + members: null, + id: null, }; try{ const res = await api.post('/message', message); @@ -214,7 +233,8 @@ function Chats(){ message.id = res.data.id setMessage([...messages, res.data]); setNewMessage(""); - socket.current.emit('sendMessage', message); + if (socket.current) + socket.current.emit('sendMessage', message); } catch(err){ console.log(err) @@ -263,7 +283,7 @@ function Chats(){ // const closeBlock = () => setBlock(false); - const handleFriend = (event) => { + const handleFriend = (event: { target: { value: React.SetStateAction; }; }) => { setFriend(event.target.value); }; @@ -328,7 +348,7 @@ function Chats(){
profile - {isLoading ? ( + {isLoading || !user ? (

Loading...

) : (

{user.nickname}

@@ -417,7 +437,7 @@ function Chats(){ initial={false} onExitComplete={() => null} > - {setting && } + {setting && } @@ -458,7 +478,7 @@ function Chats(){ ))} - {conversations.map((c, index ) => { + {conversations.map((c: Conv, index ) => { return (
setCurrentChat(c)}> @@ -466,7 +486,7 @@ function Chats(){ User
{c.name} - Desc? + {/* Desc? */}
@@ -475,12 +495,12 @@ function Chats(){
{ - currentChat ? ( + currentChat && user ? ( <>
{messages.map(m=>( - + ))}
{/* */} diff --git a/containers/react/src/components/Messages/GameModal.tsx b/containers/react/src/components/Messages/GameModal.tsx index f05f2ffd..f1004eb3 100644 --- a/containers/react/src/components/Messages/GameModal.tsx +++ b/containers/react/src/components/Messages/GameModal.tsx @@ -2,10 +2,9 @@ import { motion } from "framer-motion"; import Backdrop from "../Sidebar/Backdrop.tsx"; import '../../styles/Messages.css'; import { useState, useEffect } from "react"; -import { GrAdd } from "react-icons/gr"; -import { Link } from "react-router-dom"; import api from "../../script/axiosApi.tsx"; import React from "react"; +import {User} from "../../../interfaces.tsx" // import { useNavigate } from "react-router-dom"; const dropIn = { @@ -23,10 +22,15 @@ const dropIn = { exit: { y: "100vh", opacity: 0 }, }; -const GameModal = ({ handleClose }) => { +interface ModalGame { + handleClose: Function, + // convId: string +} + +const GameModal = ({ handleClose }: ModalGame) => { const [users, setUsers] = useState([]); const [selectedUser, setSelectedUser] = useState(''); - const [convs, setConvs] = useState([]); +// const [convs, setConvs] = useState([]); const [channel, setChannel] = useState(''); // const history = useNavigate(); @@ -35,9 +39,9 @@ const GameModal = ({ handleClose }) => { const fetchData = async () => { try { const tmpUsers = await api.get("/users"); - const tmpConvs = await api.get("/convs"); + // const tmpConvs = await api.get("/convs"); setUsers(tmpUsers.data); - setConvs(tmpConvs.data); + // setConvs(tmpConvs.data); } catch (err) { console.log(err); } @@ -45,7 +49,7 @@ const GameModal = ({ handleClose }) => { fetchData(); }, []); - const handleUserChange = (event) => { + const handleUserChange = (event: { target: { value: React.SetStateAction; }; }) => { setSelectedUser(event.target.value); }; @@ -66,18 +70,19 @@ const GameModal = ({ handleClose }) => { // let path = `play?`; let path = `http://` + process.env.REACT_APP_BASE_URL + `/pong/play?`; - const superpowerCheckbox = document.querySelector('input[value="superpower"]'); - if (superpowerCheckbox.checked) { + + const superpowerCheckbox = document.querySelector('input[value="superpower"]'); + if (superpowerCheckbox && superpowerCheckbox.checked) { path += 'superpower=true&'; } - const obstacleCheckbox = document.querySelector('input[value="obstacle"]'); - if (obstacleCheckbox.checked) { + const obstacleCheckbox = document.querySelector('input[value="obstacle"]'); + if (obstacleCheckbox && obstacleCheckbox.checked) { path += 'obstacle=true&'; } - const speedCheckbox = document.querySelector('input[value="speed"]'); - if (speedCheckbox.checked) { + const speedCheckbox = document.querySelector('input[value="speed"]'); + if (speedCheckbox && speedCheckbox.checked) { path += 'speed=true&'; } @@ -91,18 +96,18 @@ const GameModal = ({ handleClose }) => { // console.log("path= ", path) // history(path, { replace: true }); // window.location.replace(path); - window.history.pushState({}, null, path); - window.location.reload(false); + window.history.pushState({}, '', path); + window.location.reload(); // history(path); }; return ( - + e.stopPropagation()} className="modal" - variant={dropIn} + // variant={dropIn} initial="hidden" animate="visible" exit="exit" @@ -110,7 +115,7 @@ const GameModal = ({ handleClose }) => {
Faster and Faster

- + {/* */}
{/*
diff --git a/containers/react/src/components/Messages/Input.tsx b/containers/react/src/components/Messages/Input.tsx index 15a49b21..868c1abe 100644 --- a/containers/react/src/components/Messages/Input.tsx +++ b/containers/react/src/components/Messages/Input.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import { TbSend } from 'react-icons/tb'; diff --git a/containers/react/src/components/Messages/Message.tsx b/containers/react/src/components/Messages/Message.tsx index fb1f6b3c..d04e250b 100644 --- a/containers/react/src/components/Messages/Message.tsx +++ b/containers/react/src/components/Messages/Message.tsx @@ -6,7 +6,7 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/01 18:24:46 by apommier #+# #+# */ -/* Updated: 2023/06/19 11:45:54 by apommier ### ########.fr */ +/* Updated: 2023/06/20 12:47:33 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,6 +17,7 @@ import DefaultPicture from '../../assets/profile.jpg' // import { useRef } from "react"; // import { useEffect } from "react"; import '../../styles/Messages.css' +import {User, Conv, Message} from "../../../interfaces.tsx" import React from "react"; const MeStyleP = styled.p` @@ -27,14 +28,19 @@ const MeStyleP = styled.p` margin-right: 20px; ` -function MessageMe({message, own}){ +interface MessageMeProps { + message: Message; + own: boolean; + } + +function MessageMe({message, own}: MessageMeProps){ const [profilePicture, setProfilePicture] = useState(''); - const [sender, setSender] = useState(); - const [conv, setConv] = useState(); + const [sender, setSender] = useState(); + const [conv, setConv] = useState(); - const [user, setUser] = useState(); - const scrollRef = useRef(); + const [user, setUser] = useState(); + const scrollRef = useRef(null); useEffect(() => { if (scrollRef.current) @@ -64,23 +70,23 @@ function MessageMe({message, own}){ const handleButtonClick = () => { if (!sender) - return; + return ; let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${sender.username}`; // console.log("path= ", path) // history(path, { replace: true }); // window.location.replace(path); - window.history.pushState({}, null, path); - window.location.reload(false); + window.history.pushState({}, '', path); + window.location.reload(); }; if (!user || !sender || !conv) - return ; + return (<>); // console.log("result includes=", conv.banned.includes(user.username)) // console.log("result includes=", conv.blocked.includes(user.username)) if (user.blocked && user.blocked.includes(message.sender)) - return ; + return (<>); else if (conv.banned && conv.banned.includes(user.username)) - return ; + return (<>); // if (user.blocked.includes(message.sender))/ return ( diff --git a/containers/react/src/components/Messages/MessageMe.tsx b/containers/react/src/components/Messages/MessageMe.tsx index a1cc13b3..82baac78 100644 --- a/containers/react/src/components/Messages/MessageMe.tsx +++ b/containers/react/src/components/Messages/MessageMe.tsx @@ -14,7 +14,8 @@ const MeStyleP = styled.p` ` function MessageMe(){ - const scrollRef = useRef(); + // const scrollRef = useRef(); + const scrollRef = useRef(null); useEffect(() => { scrollRef.current?.scrollIntoView({ behavior: "smooth"}) diff --git a/containers/react/src/components/Messages/MessageYou.tsx b/containers/react/src/components/Messages/MessageYou.tsx index b3dad724..798002a1 100644 --- a/containers/react/src/components/Messages/MessageYou.tsx +++ b/containers/react/src/components/Messages/MessageYou.tsx @@ -14,7 +14,7 @@ const StyleP = styled.p` ` function MessageYou(){ - const scrollRef = useRef(); + const scrollRef = useRef(null); useEffect(() => { scrollRef.current?.scrollIntoView({ behavior: "smooth"}) diff --git a/containers/react/src/components/Messages/Modal.tsx b/containers/react/src/components/Messages/Modal.tsx index aceb20a9..a6546944 100644 --- a/containers/react/src/components/Messages/Modal.tsx +++ b/containers/react/src/components/Messages/Modal.tsx @@ -90,7 +90,7 @@ const Modal = ({handleClose}) => { // test await api.post("/conv", data); handleClose(); - window.location.reload(false); + window.location.reload(); } catch(err) { console.log(err); } diff --git a/containers/react/src/components/Messages/ModalSetting.tsx b/containers/react/src/components/Messages/ModalSetting.tsx index 1e73932e..d0137544 100644 --- a/containers/react/src/components/Messages/ModalSetting.tsx +++ b/containers/react/src/components/Messages/ModalSetting.tsx @@ -1,12 +1,13 @@ import { motion } from "framer-motion"; import Backdrop from "../Sidebar/Backdrop.tsx"; -import { Rank } from "../../DataBase/DataRank" +// import { Rank } from "../../DataBase/DataRank" import '../../styles/Messages.css' import { useState, useEffect } from "react"; import { GrAdd } from "react-icons/gr"; import { Link } from "react-router-dom"; import api from "../../script/axiosApi.tsx"; import React from "react"; +import {User} from "../../../interfaces.tsx" const dropIn = { @@ -25,11 +26,16 @@ const dropIn = { }; -const ModalSetting = ({handleClose, convId}) => { +interface ModalSettingProps { + handleClose: Function, + convId: string +} + +const ModalSetting = ({handleClose, convId}: ModalSettingProps) => { const [password, setPassword] = useState(false); - const [users, setUsers] = useState([]); + const [users, setUsers] = useState([]); const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]); - const [selectedUser, setSelectedUser] = useState([]); + const [selectedUser, setSelectedUser] = useState(""); const [newName, setNewName] = useState(""); const [newPassword, setNewPassword] = useState(""); @@ -52,7 +58,7 @@ const ModalSetting = ({handleClose, convId}) => { // const [selectedOptionArray, setSelectedOptionArray] = useState([]); - const handleOptionChange = (selectId, selectedOption) => { + const handleOptionChange = (selectId: number, selectedOption: string) => { console.log("tag= ", selectTags) console.log("option= ", selectedOption) setSelectTag((prevTags) => @@ -63,12 +69,12 @@ const ModalSetting = ({handleClose, convId}) => { setSelectedUser(selectedOption) }; - const handleCheckPass = (e) => { + const handleCheckPass = (e: { target: { checked: boolean | ((prevState: boolean) => boolean); }; }) => { setPassword(e.target.checked); console.log("password??", e.target.checked) } - const handleCheckPriv = (e) => { + const handleCheckPriv = (e: { target: { checked: any; }; }) => { // setPassword(e.target.checked); if (e.target.checked) { @@ -90,7 +96,7 @@ const ModalSetting = ({handleClose, convId}) => { } } - const handleName = async (e)=>{ + const handleName = async (e: { key: string; })=>{ if (e.key !== "Enter") return ; try{ @@ -101,7 +107,7 @@ const ModalSetting = ({handleClose, convId}) => { handleClose(); } - const handlePassword = async (e)=>{ + const handlePassword = async (e: { key: string; })=>{ if (e.key !== "Enter") return ; try{ @@ -157,11 +163,10 @@ const ModalSetting = ({handleClose, convId}) => { }; return ( - + e.stopPropagation()} className="modalSetting" - variant={dropIn} initial="hidden" animate="visible" exit="exit" diff --git a/containers/react/src/components/Messages/PartyInvite.tsx b/containers/react/src/components/Messages/PartyInvite.tsx index e73bab4e..6bb8509d 100644 --- a/containers/react/src/components/Messages/PartyInvite.tsx +++ b/containers/react/src/components/Messages/PartyInvite.tsx @@ -6,7 +6,7 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/19 16:44:29 by apommier #+# #+# */ -/* Updated: 2023/06/19 17:26:22 by apommier ### ########.fr */ +/* Updated: 2023/06/20 03:47:52 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,7 @@ import api from '../../script/axiosApi.tsx'; import DefaultPicture from '../../assets/profile.jpg' import styled from "styled-components"; +import {User} from "../../../interfaces.tsx" import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx"; import React from "react"; @@ -38,10 +39,19 @@ const SideP = styled.p` margin-left: 15px; ` -export default function PartyInvite({currentInvite}) +interface InviteProps { + username: string, + gameId: string + } + +interface UserProps { + currentInvite: {username: string, gameId: string} + } + +export default function PartyInvite({currentInvite}: UserProps) { const [profilePicture, setProfilePicture] = useState(''); - const [request, setRequest] = useState(''); //user who invite + const [request, setRequest] = useState(); //user who invite const [clickEvent, setClickEvent] = useState(false); // const [user, setUser] = useState(null); @@ -65,18 +75,18 @@ export default function PartyInvite({currentInvite}) fetchProfilePicture(); }, [clickEvent]) - const handleButtonClick = (user) => { + const handleButtonClick = (user: InviteProps) => { let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`; // history(path, { replace: true }); // window.location.replace(path); - window.history.pushState({}, null, path); - window.location.reload(false); + window.history.pushState({}, '', path); + window.location.reload(); }; - const Accept = async (request) => { + const Accept = async (request: User) => { try{ //call canvas ?? // await api.post("/friend", {username: request.username}) @@ -85,8 +95,8 @@ export default function PartyInvite({currentInvite}) path += 'username=' + request.username; path += '&gameId=' + currentInvite.gameId; // setClickEvent(true); - window.history.pushState({}, null, path); - window.location.reload(false); + window.history.pushState({}, '', path); + window.location.reload(); } catch(err) { console.log(err); } @@ -94,7 +104,7 @@ export default function PartyInvite({currentInvite}) console.log(`request = ${request}`) } - const Refuse = async (request) => { + const Refuse = async (request: User) => { try{ await api.post("/deleteInvite", {username: request.username}) // await api.post("/refuseInvite", {username: request.username}) @@ -118,12 +128,13 @@ export default function PartyInvite({currentInvite}) ) : ( Default Profile Picture )} + {request ? (
handleButtonClick(currentInvite)}>{request.nickname} Accept(request)} color={'green'}/> Refuse(request)} color={'red'}/> -
+ ) : ( "" )} ) } \ No newline at end of file diff --git a/containers/react/src/components/Profile/EditName.tsx b/containers/react/src/components/Profile/EditName.tsx index 6b232b9c..35123169 100644 --- a/containers/react/src/components/Profile/EditName.tsx +++ b/containers/react/src/components/Profile/EditName.tsx @@ -52,7 +52,7 @@ const ModalEdit = ( handleClose ) => { console.log("nickname=" ,nickname) try{ await api.post("/nickname", {nickname: nickname}) - window.location.reload(false); + window.location.reload(); // setUser(tmpUser.data); // setIsLoading(false) } diff --git a/containers/react/src/components/Profile/Logout.tsx b/containers/react/src/components/Profile/Logout.tsx index 029078d5..81da718b 100644 --- a/containers/react/src/components/Profile/Logout.tsx +++ b/containers/react/src/components/Profile/Logout.tsx @@ -1,3 +1,4 @@ +import React from "react"; @@ -8,8 +9,9 @@ function Logout(){ // history(path, { replace: true }); // window.location.replace(path); // window.history.pushState({}, '', path); - window.history.pushState({}, null, path); - window.location.reload(false); + window.history.pushState({}, '', path); + window.location.reload(); + return (<>) } export default Logout; \ No newline at end of file diff --git a/containers/react/src/components/Profile/Win_Loss.tsx b/containers/react/src/components/Profile/Win_Loss.tsx index 26314607..99c0a969 100644 --- a/containers/react/src/components/Profile/Win_Loss.tsx +++ b/containers/react/src/components/Profile/Win_Loss.tsx @@ -4,6 +4,7 @@ // import '../DataBase/DataProfileUser.js' // import { DBWinLoss } from '../../DataBase/DummyDBWinLoss.js'; import '../../styles/Win_Loss.css' +import { User, Matchlog } from "../../../interfaces.tsx" // import { UserProfile } from '../../DataBase/DataUserProfile'; // import color from '../../utils/style/color.js'; @@ -51,7 +52,7 @@ import api from '../../script/axiosApi.tsx'; function WinLoss() { - const [user, setUser] = useState(null); + const [user, setUser] = useState(); const [history, setHistory] = useState([]); const [isLoading, setIsLoading] = useState(true); @@ -88,13 +89,13 @@ function WinLoss() {
- {isLoading ? ( + {isLoading || !history || !user ? (

Loading...

// Loading... ) : (

Match history Win/Loss

- {history.map((c, index) => { + {history.map((c: Matchlog, index) => { return (
  • diff --git a/containers/react/src/components/Sidebar/Backdrop.tsx b/containers/react/src/components/Sidebar/Backdrop.tsx index b0280956..b19352e0 100644 --- a/containers/react/src/components/Sidebar/Backdrop.tsx +++ b/containers/react/src/components/Sidebar/Backdrop.tsx @@ -1,7 +1,13 @@ +import React, { MouseEventHandler, ReactNode, HTMLAttributes } from "react"; import { motion } from "framer-motion" import "../../styles/Header.css" -const Backdrop = ({ children, onClick }) => { +interface backProps { + children: ReactNode, + onClick: any +} + +const Backdrop = ({ children, onClick }: backProps) => { return ( { +interface CloseProps { + handleclose: Function; + } + +const Modal = ({ handleclose }: CloseProps) => { return ( +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/09 08:18:58 by apommier #+# #+# */ -/* Updated: 2023/06/18 13:12:26 by apommier ### ########.fr */ +/* Updated: 2023/06/20 13:41:44 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,6 +18,7 @@ import styled from "styled-components"; import { RxCircle } from "react-icons/rx"; import { CgFontSpacing } from "react-icons/cg"; import React from "react"; +import {User} from "../../../interfaces.tsx" const UserChat = styled.div ` padding: 5px; @@ -37,8 +38,12 @@ const SideP = styled.p` color: lightgray; margin-left: 15px; ` +interface UserProps { + currentUser: User + } -export default function Friend({currentUser}) +// export default function Friend({currentUser}) +export default function Friend({currentUser}: UserProps) { const [profilePicture, setProfilePicture] = useState(''); @@ -58,7 +63,7 @@ export default function Friend({currentUser}) fetchProfilePicture(); }) - function getStatus(friend) + function getStatus(friend: User) { let status = friend.status console.log(`status= ${status}`) @@ -73,19 +78,19 @@ export default function Friend({currentUser}) return statusColor; } - const handleSpectate = (user) => { + const handleSpectate = (user: User) => { //socket connection and add to party with one with username console.log(`spectate hehe`) console.log(`user= ${user}`) }; - const handleButtonClick = (user) => { + const handleButtonClick = (user: User) => { let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`; console.log("path= ", path) // history(path, { replace: true }); // window.location.replace(path); - window.history.pushState({}, null, path); - window.location.reload(false); + window.history.pushState({}, '', path); + window.location.reload(); }; return ( @@ -97,7 +102,7 @@ export default function Friend({currentUser}) )}
    handleButtonClick(currentUser)}>{currentUser.nickname} - + {getStatus(currentUser) !== 'blue' ? ( <> diff --git a/containers/react/src/components/Social/FriendRequest.tsx b/containers/react/src/components/Social/FriendRequest.tsx index cf9af1da..7e0eb62c 100644 --- a/containers/react/src/components/Social/FriendRequest.tsx +++ b/containers/react/src/components/Social/FriendRequest.tsx @@ -6,6 +6,7 @@ import styled from "styled-components"; import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx"; import React from "react"; +import {User} from "../../../interfaces.tsx" const UserChat = styled.div ` padding: 5px; @@ -26,10 +27,14 @@ const SideP = styled.p` margin-left: 15px; ` -export default function Friend({currentUser}) +interface UserProps { + currentUser: User + } + +export default function Friend({currentUser}: UserProps) { const [profilePicture, setProfilePicture] = useState(''); - const [request, setRequest] = useState(''); //user who invite + const [request, setRequest] = useState(); //user who invite const [clickEvent, setClickEvent] = useState(false); // const [user, setUser] = useState(null); @@ -53,15 +58,15 @@ export default function Friend({currentUser}) fetchProfilePicture(); }, [clickEvent]) - const handleButtonClick = (user) => { + const handleButtonClick = (user: User) => { let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`; // history(path, { replace: true }); // window.location.replace(path); - window.history.pushState({}, null, path); - window.location.reload(false); + window.history.pushState({}, '', path); + window.location.reload(); }; - const Accept = async (request) => { + const Accept = async (request: User) => { try{ await api.post("/friend", {username: request.username}) setClickEvent(true); @@ -72,7 +77,7 @@ export default function Friend({currentUser}) console.log(`request = ${request}`) } - const Refuse = async (request) => { + const Refuse = async (request: User) => { try{ await api.post("/refuseInvite", {username: request.username}) setClickEvent(true); @@ -95,12 +100,13 @@ export default function Friend({currentUser}) ) : ( Default Profile Picture )} + {request ? (
    handleButtonClick(currentUser)}>{currentUser.nickname} Accept(request)} color={'green'}/> Refuse(request)} color={'red'}/> -
    + ) : ( "" )} ) } diff --git a/containers/react/src/components/Social/Social.tsx b/containers/react/src/components/Social/Social.tsx index f6aefd5e..40d6e4dc 100644 --- a/containers/react/src/components/Social/Social.tsx +++ b/containers/react/src/components/Social/Social.tsx @@ -9,6 +9,7 @@ import FriendRequest from './FriendRequest.tsx'; import { ImBlocked } from 'react-icons/im'; import { MdOutlineGroupAdd } from 'react-icons/md'; +import {User} from "../../../interfaces.tsx" // import React from "react"; @@ -34,12 +35,11 @@ function Social (){ const [friends, setFriends] = useState([]); const [invite, setInvite] = useState([]); - const [isLoading, setIsLoading] = useState(true); - const [user, setUser] = useState(null); + const [isLoading, setIsLoading] = useState(true); + const [user, setUser] = useState(); const [profilePicture, setProfilePicture] = useState(''); useEffect(()=> { - const getFriend = async ()=>{ try{ const tmpFriends = await api.get("/friends") @@ -94,7 +94,7 @@ function Social (){ Default Profile Picture )} - {isLoading ? ( + {isLoading || !user ? (

    Loading...

    ) : (

    {user.nickname}

    diff --git a/containers/react/src/pages/Field.tsx b/containers/react/src/pages/Field.tsx index 86de3807..1e2090d4 100644 --- a/containers/react/src/pages/Field.tsx +++ b/containers/react/src/pages/Field.tsx @@ -1,4 +1,4 @@ -import { useEffect, useLocation } from 'react'; +import { useEffect } from 'react'; // import { useState, useRef } from 'react'; import DrawCanvas from './canvas.tsx'; import queryString from 'query-string'; @@ -9,6 +9,12 @@ import React from 'react'; // import { withRouter } from 'react-router-dom'; +interface GameProps { + privateParty: boolean, + username?: string + gameId?: number +} + function Field() { useEffect(() => { @@ -17,7 +23,7 @@ function Field() console.log("launch canva hehe") let Modifiers = 0; - let info; + let info: GameProps; if (queryParams.superpower === 'true') { Modifiers += 1; @@ -33,16 +39,16 @@ function Field() info = { privateParty: false, + } if (queryParams.username) { console.log("user= ", queryParams.username) info = { privateParty: true, - username: queryParams.username, + username: queryParams.username as string, + gameId: queryParams.gameId as unknown as number } - if (queryParams.gameId) - info.gameId = queryParams.gameId console.log("info of param vefore canvas=", info) } @@ -50,9 +56,10 @@ function Field() return () => { console.log("Cleanup"); - cleanup(); // Call the cleanup function to stop the ongoing process or perform necessary cleanup tasks + // cleanup(); // Call the cleanup function to stop the ongoing process or perform necessary cleanup tasks + if (cleanup) + cleanup(); }; - }, []); // const [buttonClicked, setButtonClicked] = useState(false); diff --git a/containers/react/src/pages/Head.tsx b/containers/react/src/pages/Head.tsx index 0284f4c7..ebf206d9 100644 --- a/containers/react/src/pages/Head.tsx +++ b/containers/react/src/pages/Head.tsx @@ -1,3 +1,5 @@ +import React from "react"; + function Head() { return ( @@ -7,7 +9,7 @@ function Head() BEST PONG EVER {/* */} - + {/* */}
    ); diff --git a/containers/react/src/pages/Home.tsx b/containers/react/src/pages/Home.tsx index 0f5f40db..4e59a416 100644 --- a/containers/react/src/pages/Home.tsx +++ b/containers/react/src/pages/Home.tsx @@ -6,7 +6,7 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/09 08:19:04 by apommier #+# #+# */ -/* Updated: 2023/06/19 20:27:00 by apommier ### ########.fr */ +/* Updated: 2023/06/20 15:27:00 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -30,8 +30,9 @@ import { IoCloseCircleOutline } from "react-icons/io5"; // import * as React from 'react'; // import { useState, useEffect, useParams} from "react"; -import React, { useState, useEffect, useRef } from "react"; +import React, { useState, useEffect, useRef, ChangeEventHandler } from "react"; import { useParams } from 'react-router-dom'; +import {User, Conv} from "../../interfaces.tsx" // axios.get("http://localhost/api") // .then((response) => { // response = response.json() @@ -43,41 +44,89 @@ import { useParams } from 'react-router-dom'; function Profile () { - const [user, setUser] = useState(null); - const [isLoading, setIsLoading] = useState(true); - const [modalOpen, setModalOpen] = useState(false); - const [mine, setMine] = useState(false); + const [user, setUser] = useState(); + const [isLoading, setIsLoading] = useState(true); + const [modalOpen, setModalOpen] = useState(false); + const [mine, setMine] = useState(false); const close = () => setModalOpen(false); const open = () => setModalOpen(true); const { username } = useParams(); - const [selectedPhoto, setSelectedPhoto] = useState(null); + // const [selectedPhoto, setSelectedPhoto] = useState(); + // const [selectedPhoto, setSelectedPhoto] = useState(null); + const [profilePicture, setProfilePicture] = useState(''); - const handleFileChange = (event) => { - // const file = event.target.files[0]; - setSelectedPhoto(event.target.files[0]); - // try{ - // api.post("/picture", {picture: URL.createObjectURL(file)}) - // } - // catch(err){ - // console.log(err); - // } - }; + // const handleFileChange = (event: { target: { files: React.SetStateAction[]; }; }) => { + // // const file = event.target.files[0]; + // setSelectedPhoto(event.target.files[0]); + // // try{ + // // api.post("/picture", {picture: URL.createObjectURL(file)}) + // // } + // // catch(err){ + // // console.log(err); + // // } + // }; - 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(false); - } catch (error) { - console.error('Error uploading file:', error); - } + // const handleFileChange = (event: { target: { files: React.SetStateAction[] | FileList; }; }) => { + // const files = event.target.files; + // if (event.target.files && event.target.files.length > 0) { + // setSelectedPhoto(event.target.files[0]); + // } + // }; + + const handleFileChange = async (event: { target: { files: any; }; }) => { + // const files = event.target.files; + // if (files && files.length > 0) { + const photo = (event.target.files[0]); + console.log("file selected") + if (photo) { + console.log("selected photo") + const formData = new FormData(); + formData.append('photo', photo); + try { + await api.post('/picture', formData); + console.log('File uploaded successfully'); + window.location.reload(); + } catch (error) { + console.error('Error uploading file:', error); + } + } + // } }; + // const handleUpload = async () => { + // const 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(()=> { const getUser = async ()=>{ console.log(`username= ${username}`) @@ -122,7 +171,7 @@ function Profile () { Default Profile Picture )} - {isLoading ? ( + {isLoading || !user ? (

    Loading...

    ) : (

    {user.nickname}

    @@ -142,7 +191,8 @@ function Profile () {
    - + {/* */} + {/* */}
  • ) : ( diff --git a/containers/react/src/pages/Login42.tsx b/containers/react/src/pages/Login42.tsx index e69c9e8e..c47c8421 100644 --- a/containers/react/src/pages/Login42.tsx +++ b/containers/react/src/pages/Login42.tsx @@ -1,6 +1,7 @@ // 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'; @@ -37,7 +38,7 @@ function Login42() return (
    -

    "COUCOU LOGIN$@ jeje"

    +

    "COUCOU LOGIN"

    {/* */}
    ); diff --git a/containers/react/src/pages/Messages.tsx b/containers/react/src/pages/Messages.tsx index 3130e2ab..9d3ad2f2 100644 --- a/containers/react/src/pages/Messages.tsx +++ b/containers/react/src/pages/Messages.tsx @@ -6,7 +6,7 @@ import { motion } from 'framer-motion' // import {io} from 'socket.io-client' -function Messages(params) { +function Messages() { // const socket = useRef(io("ws://localhost:8900")) // useEffect(() => { diff --git a/containers/react/src/pages/NewLogin.tsx b/containers/react/src/pages/NewLogin.tsx index 4e98f900..e87c603d 100644 --- a/containers/react/src/pages/NewLogin.tsx +++ b/containers/react/src/pages/NewLogin.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import '../styles/field.css'; // import { useHistory } from 'react-router-dom'; import { useNavigate } from "react-router-dom"; diff --git a/containers/react/src/pages/QrCode.tsx b/containers/react/src/pages/QrCode.tsx index ad9f2367..2dcca83f 100644 --- a/containers/react/src/pages/QrCode.tsx +++ b/containers/react/src/pages/QrCode.tsx @@ -29,9 +29,10 @@ const qrCode = new QRCodeStyling({ function QrCode () { // const url = "https://www.youtube.com"; - const ref = useRef(null); + // const ref = useRef(null); + const ref = useRef(null); const [user, setUser] = useState(false); - const [url, setUrl] = useState(false); + const [url, setUrl] = useState(""); const [secret, setSecret] = useState(false); const [code, setCode] = useState(''); const [activated, setActivated] = useState(false); @@ -39,8 +40,8 @@ function QrCode () { // const history = useHistory(); useEffect(() => { - qrCode.append(ref.current); - + if (ref.current) + qrCode.append(ref.current); const getUser = async ()=>{ try{ const tmpUser = await api.get("/profile"); @@ -66,13 +67,11 @@ function QrCode () { }, []); useEffect(() => { - qrCode.update({ - data: url - }); + qrCode.update({data: url}); }, [url]); - const handleKeyPress = async (e)=>{ + const handleKeyPress = async (e: { key: string; })=>{ // console.log(`e in press= ${e.key}`) if (e.key !== "Enter") return ; @@ -87,8 +86,8 @@ function QrCode () { // history.push('/login') const path = 'http://' + process.env.REACT_APP_BASE_URL + '/'; - window.history.pushState({}, null, path); - window.location.reload(false); + window.history.pushState({}, '', path); + window.location.reload(); } else @@ -107,8 +106,8 @@ function QrCode () { try { await api.post("/deleteOtp") // const path = 'http://' + process.env.REACT_APP_BASE_URL + '/'; - // window.history.pushState({}, null, path); - window.location.reload(false); + // window.history.pushState({}, '', path); + window.location.reload(); } catch(err) { console.log(err); } @@ -139,6 +138,7 @@ function QrCode () {

    {secret}

    Or Scan The QRCode

    + {/*
    {ref}
    */} )} diff --git a/containers/react/src/pages/canvas.tsx b/containers/react/src/pages/canvas.tsx index b02274ae..7cef82fe 100644 --- a/containers/react/src/pages/canvas.tsx +++ b/containers/react/src/pages/canvas.tsx @@ -8,7 +8,13 @@ import io from 'socket.io-client'; // const socket = io('http://86.209.110.20:4000'); // const socket = io('http://172.29.113.91:4000'); -function DrawCanvas(option: number, gameParam) { +interface GameProps { + privateParty: boolean, + username?: string + gameId?: number +} + +function DrawCanvas(option: number, gameParam: GameProps) { console.log(`option= ${option}`); const superpowerModifier = option & 1; // Retrieves the superpower modifier @@ -23,7 +29,6 @@ function DrawCanvas(option: number, gameParam) { // const socketRef = useRef(null); // socketRef.current = io('http://localhost:4000'); - const socket = io('http://' + process.env.REACT_APP_BASE_URL + ':4000'); function launchGame() { @@ -43,17 +48,22 @@ function DrawCanvas(option: number, gameParam) { joinPrivateParty(); } } - + // const socket = socketRef.current console.log("start function"); - let canvas; - canvas = document.getElementById('myCanvas'); + // let canvas: HTMLElement | null; + const canvas = document.getElementById('myCanvas') as HTMLCanvasElement | null;; + if (!canvas) + return ; const ctx = canvas.getContext('2d'); + if(!ctx) + return ; + const socket = io('http://' + process.env.REACT_APP_BASE_URL + ':4000'); // useEffect(() => { - // console.log("useeffect?????????????????") + // console.log("useeffect?????????????????") // return () => { // console.log("000000000000000000000000000000000") // socketRef.current.disconnect(); @@ -70,8 +80,8 @@ function DrawCanvas(option: number, gameParam) { //socket let myId = 0; let gameId = 0; - let opName; - let opRank; + let opName: string + let opRank: number; //general canvas let running = true; @@ -143,7 +153,7 @@ socket.on('pong:win', async () => { socket.emit('pong:disconnect', {id: myId}); console.log("before reload") window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong"); - // window.location.reload(false); + // window.location.reload(); return ; // console.log("send all ?? win"); @@ -286,7 +296,7 @@ socket.on('pong:point', (data) => { function send_info() { - if (gameId === 0) + if (!gameId || !canvas) return ; const info = { id: myId, @@ -304,7 +314,7 @@ socket.on('pong:point', (data) => { function send_point() { - if (gameId === 0) + if (!gameId || !canvas) return ; console.log("send point"); const info = { @@ -317,7 +327,7 @@ socket.on('pong:point', (data) => { function send_paddle_info() { - if (gameId === 0) + if (!gameId || !canvas) return ; const info = { id: myId, @@ -331,6 +341,8 @@ socket.on('pong:point', (data) => { function use_power() { + if (!canvas) + return ; const info = { gameId: gameId, width: canvas.width, @@ -342,7 +354,7 @@ socket.on('pong:point', (data) => { function send_forced_info() { - if (gameId === 0) + if (!gameId || !canvas) return ; const info = { gameId: gameId, @@ -367,6 +379,8 @@ socket.on('pong:point', (data) => { function drawcenter() { // ctx.restore(); + if (!ctx || !canvas) + return ; ctx.fillStyle = 'white'; ctx.fillRect(canvas.width / 2 - ctx.lineWidth / 2, 0, canvas.width / 300, canvas.height); @@ -379,11 +393,13 @@ socket.on('pong:point', (data) => { ctx.font = canvas.width * 0.1 + "px Arial"; ctx.textAlign = "center"; ctx.textBaseline = "middle"; - ctx.fillText(myScore, canvas.width/4, canvas.height/8); - ctx.fillText(hisScore, canvas.width/1.25, canvas.height/8); + ctx.fillText(myScore.toString(), canvas.width/4, canvas.height/8); + ctx.fillText(hisScore.toString(), canvas.width/1.25, canvas.height/8); } function drawPaddle() { + if (!ctx || !canvas) + return ; ctx.fillStyle = 'white'; ctx.fillRect(paddleX, paddleY, paddleWidth, paddleHeight); ctx.fillRect(canvas.width - paddleX - paddleWidth, oPaddleY, paddleWidth, opPaddleHeight); @@ -391,6 +407,8 @@ socket.on('pong:point', (data) => { function drawball() { + if (!ctx) + return ; ctx.beginPath(); ctx.arc(ballX, ballY, ballRadius, 0, 2 * Math.PI); // ctx.lineWidth = 2; @@ -432,17 +450,17 @@ socket.on('pong:point', (data) => { } socket.emit('pong:disconnect', {id: myId}); window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong"); - // window.location.reload(false); + // window.location.reload(); // Perform any necessary cleanup tasks // ... }; -async function draw(timestamp) +async function draw(timestamp: number) { console.log("turning, running= ", running); if (!running) return ; - if (gameId === 0 ) + if (!gameId || !canvas ) { // console.log("nogameid score= ", myScore); requestAnimationFrame(draw); @@ -473,7 +491,7 @@ async function draw(timestamp) console.log("send loose"); } window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong"); - // window.location.reload(false); + // window.location.reload(); return ; } @@ -482,6 +500,9 @@ async function draw(timestamp) ballX += vX * deltaTime * canvas.width; ballY += vY * deltaTime * canvas.height; + if (!ctx) + return ; + // requestAnimationFrame(draw); ctx.clearRect(0, 0, canvas.width, canvas.height); drawPaddle(); drawcenter(); @@ -518,14 +539,17 @@ async function draw(timestamp) } - function updatePaddlePosition(newY) + function updatePaddlePosition(newY: number) { - if (newY >= 0 && newY <= canvas.height - paddleHeight) + + if (canvas && newY >= 0 && newY <= canvas.height - paddleHeight) paddleY = newY; } function is_collision() { + if (!canvas) + return ; if (ballX <= paddleX + paddleWidth + ballRadius) { if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)//touch paddle @@ -559,6 +583,8 @@ async function draw(timestamp) function is_out() { + if (!canvas) + return ; if (ballX < 0) { if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius) @@ -605,12 +631,18 @@ async function draw(timestamp) //======================================================================================================== //======================================================================================================== - document.addEventListener('resize', event => { - // event.height - // event.width - const { clientWidth, clientHeight } = canvas.parentElement; - console.log(`resize detected widht= ${clientWidth} height= ${clientHeight}`) - }); +// interface sizeProps { +// clientWidth: number, +// clientHeight: number +// } + + // document.addEventListener('resize', event => { + // // event.height + // // event.width + // const { clientWidth, clientHeight } = canvas.parentElement; + // // const { clientWidth, clientHeight } = canvas.parentElement!; + // console.log(`resize detected widht= ${clientWidth} height= ${clientHeight}`) + // }); document.addEventListener('mousemove', event => { const mouseY = event.clientY; diff --git a/containers/react/src/script/tokenSuccess.tsx b/containers/react/src/script/tokenSuccess.tsx index 5eb24530..fac964e4 100644 --- a/containers/react/src/script/tokenSuccess.tsx +++ b/containers/react/src/script/tokenSuccess.tsx @@ -68,8 +68,8 @@ function SuccessToken() { window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong"); // const path = 'http://' + process.env.REACT_APP_BASE_URL + '/'; - // window.history.pushState({}, null, path); - // window.location.reload(false); + // window.history.pushState({}, '', path); + // window.location.reload(); } else @@ -197,8 +197,8 @@ function SuccessToken() { // // history.push('/login') // const path = 'http://' + process.env.REACT_APP_BASE_URL + '/'; -// window.history.pushState({}, null, path); -// window.location.reload(false); +// window.history.pushState({}, '', path); +// window.location.reload(); // } // else diff --git a/containers/react/src/styles/Messages.css b/containers/react/src/styles/Messages.css index 0d201718..57bbe076 100644 --- a/containers/react/src/styles/Messages.css +++ b/containers/react/src/styles/Messages.css @@ -32,6 +32,7 @@ select{ display: flex; flex-direction: column; align-items: center; + overflow-x: scroll; } .scroll{ @@ -50,7 +51,8 @@ select{ .contact{ background-color: rgb(46, 46, 46); align-items: left; - height: 30.2rem; + height: 74vh; + width: 30%; overflow: scroll; /* width: 2rem; */ /* height: 4rem; */ @@ -92,6 +94,8 @@ select{ } .navbar{ + /* width: clamp(50%, 500px, 20%); */ + /* height: min(50%, 100px); */ display: flex; align-items: center; /* background-color: yellow; */ @@ -130,6 +134,7 @@ select{ background-color: rgb(26, 26, 26); /* height: calc(100% - 118px); */ width: 70%; + /* height: 300px; */ overflow: scroll; } @@ -169,11 +174,17 @@ input{ .messageContent{ display: flex; + flex-wrap: wrap; flex-direction: column; max-width: 80%; gap: 10px; } +p { + overflow-wrap: break-word; + max-width: 300px; +} + .meMessage{ display: flex; flex-direction: row-reverse; diff --git a/containers/react/src/styles/Profile.css b/containers/react/src/styles/Profile.css index aa1a90fd..6d41023c 100644 --- a/containers/react/src/styles/Profile.css +++ b/containers/react/src/styles/Profile.css @@ -54,11 +54,7 @@ - - - - - + diff --git a/containers/react/src/styles/old.css b/containers/react/src/styles/old.css index 41525064..7e15c34d 100644 --- a/containers/react/src/styles/old.css +++ b/containers/react/src/styles/old.css @@ -77,11 +77,6 @@ input{ text-decoration: none; } -label{ -} - -.login { -} .loginForm { align-items: center; diff --git a/containers/react/tsconfig.json b/containers/react/tsconfig.json new file mode 100644 index 00000000..bd4507fe --- /dev/null +++ b/containers/react/tsconfig.json @@ -0,0 +1,111 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + "jsx": "react", + "noEmit": true, + "allowImportingTsExtensions": true, + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/containers/test b/containers/test deleted file mode 100644 index f7eced04..00000000 --- a/containers/test +++ /dev/null @@ -1,2 +0,0 @@ -cc toi -cc 2 \ No newline at end of file From 93ed2a7eff39914874e868b5447ced7e7a1ff48d Mon Sep 17 00:00:00 2001 From: Little Dipper Date: Wed, 21 Jun 2023 01:57:37 +0200 Subject: [PATCH 05/13] input to select ajout mot de si channel prive --- ...1104986_download-medal-hd-png-download.png | Bin 0 -> 50083 bytes ...al-olympic-medal-bronze-medal-clip-art.png | Bin 0 -> 43456 bytes .../assets/Silver-Medal-PNG-Image-0986sd.jpg | Bin 0 -> 152501 bytes ...l-png-favpng-WmKbe5M1ptvCs0UCUQiCXiHBA.jpg | Bin 0 -> 60648 bytes .../react/src/components/Messages/Chats.tsx | 40 ++++++++++++++++-- .../react/src/components/Messages/Modal.tsx | 4 ++ containers/react/src/styles/Messages.css | 10 ++++- 7 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 containers/react/src/assets/110-1104986_download-medal-hd-png-download.png create mode 100644 containers/react/src/assets/81-810382_gold-medal-olympic-medal-bronze-medal-clip-art.png create mode 100644 containers/react/src/assets/Silver-Medal-PNG-Image-0986sd.jpg create mode 100644 containers/react/src/assets/silver-medal-gold-medal-png-favpng-WmKbe5M1ptvCs0UCUQiCXiHBA.jpg diff --git a/containers/react/src/assets/110-1104986_download-medal-hd-png-download.png b/containers/react/src/assets/110-1104986_download-medal-hd-png-download.png new file mode 100644 index 0000000000000000000000000000000000000000..7fa542459158a7a11a40dc098e3afc74846e9630 GIT binary patch literal 50083 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 Mt;>LoLBA*e8?n2@IRF3v literal 0 HcmV?d00001 diff --git a/containers/react/src/assets/81-810382_gold-medal-olympic-medal-bronze-medal-clip-art.png b/containers/react/src/assets/81-810382_gold-medal-olympic-medal-bronze-medal-clip-art.png new file mode 100644 index 0000000000000000000000000000000000000000..1617c25d998b5759257960227f228617d6168021 GIT binary patch literal 43456 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 literal 0 HcmV?d00001 diff --git a/containers/react/src/assets/Silver-Medal-PNG-Image-0986sd.jpg b/containers/react/src/assets/Silver-Medal-PNG-Image-0986sd.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6ca1316de9996e53775cf8e24e30dc286fbd9468 GIT binary patch literal 152501 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�ebNv>BT8v`UCkNZqhIb2cg36?O7YzS) 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 literal 0 HcmV?d00001 diff --git a/containers/react/src/assets/silver-medal-gold-medal-png-favpng-WmKbe5M1ptvCs0UCUQiCXiHBA.jpg b/containers/react/src/assets/silver-medal-gold-medal-png-favpng-WmKbe5M1ptvCs0UCUQiCXiHBA.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7bfd217d5babe11751981fc17b3b86db34e84357 GIT binary patch literal 60648 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 OJanB0x=w=q|4jf|LYlJx literal 0 HcmV?d00001 diff --git a/containers/react/src/components/Messages/Chats.tsx b/containers/react/src/components/Messages/Chats.tsx index 0ada4409..9805e584 100644 --- a/containers/react/src/components/Messages/Chats.tsx +++ b/containers/react/src/components/Messages/Chats.tsx @@ -107,12 +107,16 @@ function Chats(){ const convs = await api.get("/conv") const tmpInvite = await api.get("/partyInvite") const tmpUser = await api.get("/profile") + const tmpUsers = await api.get("/users"); + console.log(convs); // console.log("invite data use effect= ", tmpInvite.data); setPartyInvite(tmpInvite.data); setUser(tmpUser.data); setConversation(convs.data); + setUsers(tmpUsers.data); + // console.log(`connection....`); socket.current = io('http://' + process.env.REACT_APP_BASE_URL + ':4001', { transports: ['polling'] }); // console.log(`connection done`); @@ -255,6 +259,10 @@ function Chats(){ const [newGameModalOpen, setNewGameModalOpen] = useState(false); const [newConversationModalOpen, setNewConversationModalOpen] = useState(false); + + const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]); + const [users, setUsers] = useState([]); + const openNewGameModal = () => { setNewGameModalOpen(true); @@ -335,6 +343,15 @@ function Chats(){ setShowBlockAlert(false); }; + const handleOptionChange = (selectId, selectedOption) => { + console.log("selected Option=", selectedOption) + setSelectTag((prevTags) => + prevTags.map((tag) => + tag.id === selectId ? { ...tag, selectedOption } : tag + ) + ); + }; + //======================================================================================================== //======================================================================================================== // HTML @@ -399,9 +416,26 @@ function Chats(){ ):("")}

    */} -
    - - +
    + {selectTags.map((selectTag) => ( +
    + +
    + ))} + diff --git a/containers/react/src/components/Messages/Modal.tsx b/containers/react/src/components/Messages/Modal.tsx index a6546944..16a50bce 100644 --- a/containers/react/src/components/Messages/Modal.tsx +++ b/containers/react/src/components/Messages/Modal.tsx @@ -155,6 +155,10 @@ const Modal = ({handleClose}) => { ))} )} + {channel.private ? ( + + ):("")} +
    Join diff --git a/containers/react/src/styles/Messages.css b/containers/react/src/styles/Messages.css index 57bbe076..88a6d3d3 100644 --- a/containers/react/src/styles/Messages.css +++ b/containers/react/src/styles/Messages.css @@ -315,4 +315,12 @@ input.in{ color: white; border-radius: 12px; width: 70%; -} \ No newline at end of file +} + +.mdp{ + background-color : black; + border-radius: 8px; + color: white; + width: 20%; +} + From 90c3e3e0b7e135a488175ccbf536a007f74aefb5 Mon Sep 17 00:00:00 2001 From: kinou-p Date: Wed, 21 Jun 2023 02:11:11 +0200 Subject: [PATCH 06/13] fix bug pong decconection and win/loss fix history fix mute ? ban --- .env | 6 +- containers/api/src/app.controller.ts | 24 ++- containers/api/src/chat/chat.service.ts | 3 +- containers/api/src/users/users.service.ts | 3 +- containers/chat/src/chat/chat.gateway.ts | 159 +++++++----------- containers/pong/src/pong/pong.gateway.ts | 81 +++++---- containers/react/.env | 2 +- .../react/src/components/Messages/Chats.tsx | 39 ++++- .../src/components/Messages/GameModal.tsx | 29 ++-- .../react/src/components/Messages/Message.tsx | 15 +- .../react/src/components/Messages/Modal.tsx | 4 +- .../src/components/Messages/ModalSetting.tsx | 30 ++-- .../src/components/Messages/PartyInvite.tsx | 6 +- containers/react/src/pages/canvas.tsx | 28 +-- 14 files changed, 230 insertions(+), 199 deletions(-) diff --git a/.env b/.env index aae0c767..4b96a475 100644 --- a/.env +++ b/.env @@ -14,9 +14,9 @@ NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf" # BASE_URL=http://localhost -BASE_URL=localhost -REACT_APP_BASE_URL=localhost -REDIRECT_URI=http://localhost/api/auth/login +BASE_URL=92.143.191.152 +REACT_APP_BASE_URL=92.143.191.152 +REDIRECT_URI=http://92.143.191.152/api/auth/login #postgres var # POSTGRES_HOST=127.0.0.1 # DB_TYPE=postgres diff --git a/containers/api/src/app.controller.ts b/containers/api/src/app.controller.ts index 47c17ed7..24d6d00e 100644 --- a/containers/api/src/app.controller.ts +++ b/containers/api/src/app.controller.ts @@ -6,7 +6,7 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/17 01:00:00 by apommier #+# #+# */ -/* Updated: 2023/06/19 19:48:52 by apommier ### ########.fr */ +/* Updated: 2023/06/21 01:19:01 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -220,7 +220,10 @@ export class AppController { @UseGuards(JwtAuthGuard) @Post('/win') async addWin(@Request() req, @Body() data: any) { + console.log("WIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIN: ", 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++; const Esp = 1 / (1 + Math.pow(10, (data.opRank - user.rank) / this.scaleFactor)) const newRank = user.rank + this.kFactor * (1 - Esp); @@ -234,14 +237,16 @@ export class AppController { newMatch.opScore = data.opScore; newMatch.opponent = data.opName; newMatch.parent = user; - + console.log(`newMatch WIIIN = ${newMatch}`); await this.userService.saveChild(user, newMatch); } @UseGuards(JwtAuthGuard) @Post('/loss') async addLoss(@Request() req, @Body() data: any) { + console.log("LOOOOOOOOOOOOOOOSE: ", req.user.username) const user = await this.userService.findOne(req.user.username); + console.log("User", user) user.loss++; const Esp = 1 / (1 + Math.pow(10, (data.opRank - user.rank) / this.scaleFactor)) @@ -256,7 +261,7 @@ export class AppController { newMatch.opScore = data.opScore; newMatch.opponent = data.opName; newMatch.parent = user; - + console.log(`newMatch Loose= ${newMatch}`); await this.userService.saveChild(user, newMatch); } @@ -292,10 +297,10 @@ export class AppController { @UseGuards(JwtAuthGuard) @Get('/partyInvite') - async getPartyInvite(@Body() data: any) + async getPartyInvite(@Request() req, @Body() data: any) { //find data.username and add invite to list - const user = await this.userService.findOne(data.username); + const user = await this.userService.findOne(req.user.username); user.partyInvite = user.partyInvite || []; // this.userService.save(user); // user.partyInvite.push(data); @@ -308,8 +313,13 @@ export class AppController { async deleteInvite(@Request() req, @Body() data: any) { console.log("delete invite user= ", data.username) - const user = await this.userService.findOne(data.username); - user.partyInvite = user.partyInvite.filter(item => Object.values(item)[1] !== 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); + console.log("user.partyInvite after", user.partyInvite) this.userService.save(user); } diff --git a/containers/api/src/chat/chat.service.ts b/containers/api/src/chat/chat.service.ts index 25a5a626..b912ff83 100644 --- a/containers/api/src/chat/chat.service.ts +++ b/containers/api/src/chat/chat.service.ts @@ -6,7 +6,7 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/17 01:00:25 by apommier #+# #+# */ -/* Updated: 2023/06/18 13:14:51 by apommier ### ########.fr */ +/* Updated: 2023/06/20 16:47:02 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -85,6 +85,7 @@ async banUser(convId: number, username: string) { conv.banned = conv.banned || []; if (conv.banned.find(item => item === username)) return (1); + conv.members = conv.members.filter((item) => item !== username); conv.banned.push(username); this.save(conv); } diff --git a/containers/api/src/users/users.service.ts b/containers/api/src/users/users.service.ts index 45a9e1e4..1e078d57 100644 --- a/containers/api/src/users/users.service.ts +++ b/containers/api/src/users/users.service.ts @@ -6,7 +6,7 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/17 01:00:07 by apommier #+# #+# */ -/* Updated: 2023/06/17 01:00:08 by apommier ### ########.fr */ +/* Updated: 2023/06/21 01:31:44 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -47,6 +47,7 @@ export class UsersService { async saveChild(user: User, match: MatchLog): Promise { // user.match = savedChild; + user.children.push(match) await this.matchRepository.save(match); return await this.userRepository.save(user); } diff --git a/containers/chat/src/chat/chat.gateway.ts b/containers/chat/src/chat/chat.gateway.ts index 0f44fe1f..405bd818 100644 --- a/containers/chat/src/chat/chat.gateway.ts +++ b/containers/chat/src/chat/chat.gateway.ts @@ -98,85 +98,80 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa } } - @SubscribeMessage('socket.io') - socketConnect(client: any, payload: any): void { - console.log("/socket.io") +// @SubscribeMessage('socket.io') +// socketConnect(client: any, payload: any): void { +// console.log("/socket.io") +// } + +@SubscribeMessage('ban') +banUser(client: any, payload: any): void { + if (!this.clientsNames.has(payload.username)) + { + console.log("No user found."); + return; + } + const bannedClients = this.clientsNames.get(payload.username); + bannedClients.forEach(client => { + console.log("Banning client:", client); + // Perform ban operation on each client, e.g., emit a 'ban' event + console.log("clietn socket=", this.clients[client]) + this.clients[client].emit('ban', payload); + }); + // console.log("/ban") +// console.log("in ban username=", payload.username) +// if (!this.clientsNames[payload.username]) +// { +// console.log("no user ??") +// return ; +// } +// this.clientsNames[payload.username].forEach() +// console.log("client=", this.clientsNames) +// this.clients[payload.username].emit('ban', payload) +} + +@SubscribeMessage('mute') +muteUser(client: any, payload: any): void { + if (!this.clientsNames.has(payload.username)) + { + console.log("No user found."); + return; + } + const mutedClients = this.clientsNames.get(payload.username); + mutedClients.forEach(client => { + console.log("Banning client:", client); + // Perform ban operation on each client, e.g., emit a 'ban' event + console.log("clietn socket=", this.clients[client]) + this.clients[client].emit('mute', payload); + }); + console.log("/mute") } - // @SubscribeMessage('sendMessage') - // handleMessage(user: any, payload: any): void { - // console.log(`message recceveid: ${payload}`) - // console.log(`message recceveid: ${payload.sender}`) - // console.log(`message recceveid: ${payload.convId}`) - // console.log(`message recceveid: ${payload.members}`) - - // console.log(`client id: ${user.id}`) - - // this.clientsNames.forEach((clientArray, clientName) => { - // console.log(`Clients with name ${clientName}:`); - - // // clientArray.forEach((client) => { - // this.clientsNames[clientName] - // // .forEach(client => { - // // // if(client.id != user.id) - // // // { - // // console.log("send to someone") - // // console.log(client); // Perform actions on each client - // // // clients.emit('message', payload) - // // client.emit('message') - // // // } - // // }); - - // // .forEach((client) => { - // // if(client.id != user.id) - // // { - // // console.log("send to someone") - // // console.log(client); // Perform actions on each client - // // // clients.emit('message', payload) - // // client.emit('message') - // // } - // }); - // }; - @SubscribeMessage('sendMessage') 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}`); + // 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) => { - console.log(` 5Clients with name ${clientName}:`); + // console.log(` 5Clients with name ${clientName}:`); if (payload.members.includes(clientName)) { clientArray.forEach((targetClient, index) => { - console.log(`client id: ${client.id}`); - console.log(`target: ${targetClient}`); - console.log(`target id: ${targetClient}`); + // console.log(`client id: ${client.id}`); + // console.log(`target: ${targetClient}`); + // console.log(`target id: ${targetClient}`); if (targetClient && targetClient !== client.id) { - console.log("Sending to someone"); - console.log(`index= ${index}`); - console.log(`target: ${targetClient}`); // Perform actions on each target client - // targetClient.emit('message') - // this.clientsNames[clientName].emit('message') - // this.clientsNames["apommier"].emit('message') + // 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) - // console.log(test) - // console.log(test) - // this.clientsNames[clientName][index].emit('message'); - // const socket = this.server.sockets.sockets.get(targetClient.id); - // if (socket) { - // socket.emit('message', payload); - // } else { - // console.log(`Socket with ID ${client.id} not found.`); - // } - // targetClient.emit('message', payload); - // targetClient.emit('message', payload); + } else { console.log("not sending"); @@ -191,41 +186,3 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa - - // for (let key in this.clientsNames) { - // if (payload.members.includes(key)) { - // console.log("Key exists in the array"); - // // if (key !== payload.sender) - // // { - // for (let key2 in this.clientsNames[key]) - // { - // if (client.id !== this.clientsNames[key][key2]) - // { - // console.log("send to someone") - // this.clientsNames[key][key2].emit('message', payload) - // } - // } - // // } - // //if member socket different from mine - // //send - // } else { - // console.log("Key does not exist in the array"); - // } - //if key is in member - - // let socket = this.clients[key]; - // console.log("Clé:", key); - // console.log("Socket:", socket); - // } - // payload.convId // conv user instead ? - //find user to send message to - //const res = { - //convId: payload.convId - //sender: payload.sender - - // } - //while (user of conv)//how to get conv user - // if (user connected) - //send res to user -// } - diff --git a/containers/pong/src/pong/pong.gateway.ts b/containers/pong/src/pong/pong.gateway.ts index a136302d..42e1b648 100644 --- a/containers/pong/src/pong/pong.gateway.ts +++ b/containers/pong/src/pong/pong.gateway.ts @@ -6,7 +6,7 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/19 15:18:38 by apommier #+# #+# */ -/* Updated: 2023/06/19 21:38:55 by apommier ### ########.fr */ +/* Updated: 2023/06/21 00:59:39 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -53,26 +53,53 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa // console.log(`Client disconnected: ${client.id}`); console.log(`Normal disconnected: ${client.id}`); // this.waitingClients.delete(client); - this.waitingClients.forEach((waitingClient) => { - if (waitingClient.client === client) { - this.waitingClients.delete(waitingClient); - }}) - delete this.clients[client.id]; - console.log(`Total connected clients: ${Object.keys(this.clients).length}`); - } + // this.waitingClients.forEach((waitingClient) => { + // if (waitingClient.client === client) { + // this.waitingClients.delete(waitingClient); + // }}) + // delete this.clients[client.id]; - - @SubscribeMessage('pong:disconnect') - disconnectClient(client: Socket, payload: any): void { - console.log("disconnect forced client= ", client.id) - - for (const key in this.clients) { - if (this.clients.hasOwnProperty(key) && this.clients[key] === client) - delete this.clients[key]; - } - - // Delete the socket from the 'waitingClients' set - this.waitingClients.forEach((item) => { + this.waitingClients.forEach((item) => { + if (item.client === client) + this.waitingClients.delete(item); + }); + + // Delete the socket from the 'games' map + this.games.forEach((sockets, gameId) => { + const index = sockets.indexOf(client); + if (index !== -1) + { + if (index === 0) + { + console.log("emit boy1") + sockets[1].emit("pong:win") + // sockets[0].emit("/win") + } + else + { + console.log("emit boy2") + sockets[0].emit("pong:win") + // sockets[1].emit("/win") + } + this.games.delete(gameId); + delete this.clients[client.id]; + } + }) + + console.log(`Total connected clients: ${Object.keys(this.clients).length}`); + } + + + @SubscribeMessage('pong:disconnect') + disconnectClient(client: Socket, payload: any): void { + console.log("disconnect forced client= ", client.id) + + for (const key in this.clients) { + if (this.clients.hasOwnProperty(key) && this.clients[key] === client) + delete this.clients[key]; + } + // Delete the socket from the 'waitingClients' set + this.waitingClients.forEach((item) => { if (item.client === client) this.waitingClients.delete(item); }); @@ -82,7 +109,6 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa const index = sockets.indexOf(client); if (index !== -1) { - if (index === 0) { console.log("emit boy1") @@ -95,19 +121,6 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa sockets[0].emit("pong:win") // sockets[1].emit("/win") } - // let playersIds = - // const playersIds = this.games.get(gameId).map(socket => socket.id); - // // if (playersIds[0] === payload.id) - // // { - // if (this.clients[playersIds[1]]) - // this.clients[playersIds[1]].emit('pong:win'); - // if (this.clients[playersIds[0]]) - // this.clients[playersIds[0]].emit('pong:win'); - // } - // if (playersIds[1] === payload.id) - // { - // } - //send victory to the other one this.games.delete(gameId); delete this.clients[client.id]; } diff --git a/containers/react/.env b/containers/react/.env index 35542322..422ef8df 100644 --- a/containers/react/.env +++ b/containers/react/.env @@ -1,4 +1,4 @@ -REACT_APP_BASE_URL=localhost +REACT_APP_BASE_URL=92.143.191.152 REACT_APP_API_SECRET=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 REACT_APP_CLIENT_UID=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41 # REACT_APP_BASE_URL=92.143.191.152 diff --git a/containers/react/src/components/Messages/Chats.tsx b/containers/react/src/components/Messages/Chats.tsx index 0ada4409..a971c853 100644 --- a/containers/react/src/components/Messages/Chats.tsx +++ b/containers/react/src/components/Messages/Chats.tsx @@ -97,6 +97,7 @@ function Chats(){ // let socket: Socket; const socket = useRef(null); + // const socket = Socket | null // socket = useRef( useRef(null)); @@ -115,15 +116,22 @@ function Chats(){ setConversation(convs.data); // console.log(`connection....`); socket.current = io('http://' + process.env.REACT_APP_BASE_URL + ':4001', { transports: ['polling'] }); - // console.log(`connection done`); socket.current.emit('connection', {username: tmpUser.data.username}) - socket.current.on('message', (data) => { //data should be a message ? - // console.log(`message received data= ${data.sender}`) - // console.log(`message received data= ${data.convId}`) - // console.log(`message received data= ${data.sender}`) - // console.log(`current chat = ${currentChat}`) + socket.current.on('message', (data) => { //data should be a message ?) setIncomingMessage(data); }); + + socket.current.on('ban', (data) => { + // setIncomingMessage(data); + console.log("banned hehe"); + window.location.reload() + }); + + socket.current.on('mute', (data) => { + console.log("muted hehe"); + //set mute var to true and do nothing + }); + setIsLoading(false) } @@ -134,6 +142,14 @@ function Chats(){ }; getConv(); + return () => { + console.log("Cleanup"); + if (socket.current) + socket.current.disconnect(); + // cleanup(); // Call the cleanup function to stop the ongoing process or perform necessary cleanup tasks + // cleanup(); + }; + }, []) useEffect(()=> { @@ -175,6 +191,7 @@ function Chats(){ try { const res = await api.post('/getMessage', data); + console.log("message of conv=", res.data) setMessage(res.data); } catch(err) { @@ -198,6 +215,14 @@ function Chats(){ id: null, }; try{ + const allowed = await api.post('/allowed', {convId: currentChat.id}); + console.log("convid:", currentChat.id); + if (!allowed.data) + { + console.log("muted or banned"); + return ; + } + console.log("not muted or banned"); const res = await api.post('/message', message); const convMember = await api.post('/member', message); message.members = convMember.data.members; @@ -437,7 +462,7 @@ function Chats(){ initial={false} onExitComplete={() => null} > - {setting && } + {setting && } diff --git a/containers/react/src/components/Messages/GameModal.tsx b/containers/react/src/components/Messages/GameModal.tsx index f1004eb3..00a4a542 100644 --- a/containers/react/src/components/Messages/GameModal.tsx +++ b/containers/react/src/components/Messages/GameModal.tsx @@ -29,6 +29,7 @@ interface ModalGame { const GameModal = ({ handleClose }: ModalGame) => { const [users, setUsers] = useState([]); +// const [user, setUser] = useState(); const [selectedUser, setSelectedUser] = useState(''); // const [convs, setConvs] = useState([]); const [channel, setChannel] = useState(''); @@ -39,8 +40,10 @@ const GameModal = ({ handleClose }: ModalGame) => { const fetchData = async () => { try { const tmpUsers = await api.get("/users"); + // const tmpUser = await api.get("/profile"); // const tmpConvs = await api.get("/convs"); setUsers(tmpUsers.data); + // setUser(tmpUser.data); // setConvs(tmpConvs.data); } catch (err) { console.log(err); @@ -53,20 +56,20 @@ const GameModal = ({ handleClose }: ModalGame) => { setSelectedUser(event.target.value); }; - const joinChannel = async () => { - try { - await api.post("/join", { convId: channel }); - } catch (err) { - console.log(err); - } - }; +// const joinChannel = async () => { +// try { +// await api.post("/join", { convId: channel }); +// } catch (err) { +// console.log(err); +// } +// }; - const handleCheckButtonClick = () => { - // Perform your check action here - console.log("Checking user:", selectedUser); - }; +// const handleCheckButtonClick = () => { +// // Perform your check action here +// console.log("Checking user:", selectedUser); +// }; - const handleButtonClick = () => { + const handleButtonClick = async () => { // let path = `play?`; let path = `http://` + process.env.REACT_APP_BASE_URL + `/pong/play?`; @@ -93,6 +96,8 @@ const GameModal = ({ handleClose }: ModalGame) => { // path = path.slice(0, -1); // console.log(path) + // await api.post("/partyInvite", {username: selectedUser, gameId}) + // console.log("path= ", path) // history(path, { replace: true }); // window.location.replace(path); diff --git a/containers/react/src/components/Messages/Message.tsx b/containers/react/src/components/Messages/Message.tsx index d04e250b..b28915d6 100644 --- a/containers/react/src/components/Messages/Message.tsx +++ b/containers/react/src/components/Messages/Message.tsx @@ -6,7 +6,7 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/01 18:24:46 by apommier #+# #+# */ -/* Updated: 2023/06/20 12:47:33 by apommier ### ########.fr */ +/* Updated: 2023/06/20 19:05:10 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -42,6 +42,8 @@ function MessageMe({message, own}: MessageMeProps){ const [user, setUser] = useState(); const scrollRef = useRef(null); + // console.log("Message eher") + useEffect(() => { if (scrollRef.current) { @@ -80,13 +82,20 @@ function MessageMe({message, own}: MessageMeProps){ }; if (!user || !sender || !conv) + { + // console.log("return") return (<>); + } // console.log("result includes=", conv.banned.includes(user.username)) // console.log("result includes=", conv.blocked.includes(user.username)) if (user.blocked && user.blocked.includes(message.sender)) return (<>); - else if (conv.banned && conv.banned.includes(user.username)) - return (<>); + // else if (conv.banned && conv.banned.includes(user.username)) + // { + // console.log("return2") + // return (<>); + // } + // console.log("noy return") // if (user.blocked.includes(message.sender))/ return ( diff --git a/containers/react/src/components/Messages/Modal.tsx b/containers/react/src/components/Messages/Modal.tsx index a6546944..b7eb1d44 100644 --- a/containers/react/src/components/Messages/Modal.tsx +++ b/containers/react/src/components/Messages/Modal.tsx @@ -100,11 +100,11 @@ const Modal = ({handleClose}) => { // let new_name; return ( - + e.stopPropagation()} className="modal" - variant={dropIn} + // variant={dropIn} initial="hidden" animate="visible" exit="exit" diff --git a/containers/react/src/components/Messages/ModalSetting.tsx b/containers/react/src/components/Messages/ModalSetting.tsx index d0137544..72e623eb 100644 --- a/containers/react/src/components/Messages/ModalSetting.tsx +++ b/containers/react/src/components/Messages/ModalSetting.tsx @@ -8,6 +8,7 @@ import { Link } from "react-router-dom"; import api from "../../script/axiosApi.tsx"; import React from "react"; import {User} from "../../../interfaces.tsx" +import { Socket } from "socket.io-client"; const dropIn = { @@ -28,10 +29,11 @@ const dropIn = { interface ModalSettingProps { handleClose: Function, - convId: string + convId: string, + socket: Socket | null, } -const ModalSetting = ({handleClose, convId}: ModalSettingProps) => { +const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => { const [password, setPassword] = useState(false); const [users, setUsers] = useState([]); const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]); @@ -101,6 +103,7 @@ const ModalSetting = ({handleClose, convId}: ModalSettingProps) => { return ; try{ api.post("/name", {convId: convId, name: newName}) + window.location.reload() } catch(err) { console.log(err); } @@ -111,51 +114,56 @@ const ModalSetting = ({handleClose, convId}: ModalSettingProps) => { if (e.key !== "Enter") return ; try{ - api.post("/password", {convId: convId, password: newPassword}) + await api.post("/password", {convId: convId, password: newPassword}) } catch(err) { console.log(err); } handleClose(); } - const handleBan = () => { + const handleBan = async () => { // console.log("ban option= ", selectedUser) try{ // console.log("user select=", selectedUser.length) if (!selectedUser.length) return ; - api.post("/ban", {convId: convId, username: selectedUser}) + await api.post("/ban", {convId: convId, username: selectedUser}) + if (socket) + { + console.log("emit to ban server") + socket.emit("ban", {username: selectedUser}) + } } catch(err) { console.log(err); } handleClose(); }; - const handleAdmin = () => { + const handleAdmin = async () => { if (!selectedUser.length) return ; try{ - api.post("/admin", {convId: convId, username: selectedUser}) + await api.post("/admin", {convId: convId, username: selectedUser}) } catch(err) { console.log(err); } handleClose(); }; - const handleMute = () => { + const handleMute = async () => { if (!selectedUser.length) return ; try{ - api.post("/mute", {convId: convId, username: selectedUser}) + await api.post("/mute", {convId: convId, username: selectedUser}) } catch(err) { console.log(err); } handleClose(); }; - const handleInvite = () => { + const handleInvite = async () => { try{ - api.post("/invite", {convId: convId, username: selectedUser}) + await api.post("/invite", {convId: convId, username: selectedUser}) } catch(err) { console.log(err); } diff --git a/containers/react/src/components/Messages/PartyInvite.tsx b/containers/react/src/components/Messages/PartyInvite.tsx index 6bb8509d..791d632b 100644 --- a/containers/react/src/components/Messages/PartyInvite.tsx +++ b/containers/react/src/components/Messages/PartyInvite.tsx @@ -6,7 +6,7 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/19 16:44:29 by apommier #+# #+# */ -/* Updated: 2023/06/20 03:47:52 by apommier ### ########.fr */ +/* Updated: 2023/06/20 23:53:01 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -82,9 +82,6 @@ export default function PartyInvite({currentInvite}: UserProps) window.history.pushState({}, '', path); window.location.reload(); }; - - - const Accept = async (request: User) => { try{ @@ -118,6 +115,7 @@ export default function PartyInvite({currentInvite}: UserProps) // Vérifier si le contenu doit être caché if (clickEvent) { + console.log("retrun true") return null; // Rendre null pour ne pas afficher le contenu } diff --git a/containers/react/src/pages/canvas.tsx b/containers/react/src/pages/canvas.tsx index 7cef82fe..46dd1a58 100644 --- a/containers/react/src/pages/canvas.tsx +++ b/containers/react/src/pages/canvas.tsx @@ -61,7 +61,7 @@ function DrawCanvas(option: number, gameParam: GameProps) { if(!ctx) return ; - const socket = io('http://' + process.env.REACT_APP_BASE_URL + ':4000'); + const socket = io('http://' + process.env.REACT_APP_BASE_URL + ':4000', { transports: ['polling'] }); // useEffect(() => { // console.log("useeffect?????????????????") // return () => { @@ -137,14 +137,14 @@ function DrawCanvas(option: number, gameParam: GameProps) { socket.on('pong:win', async () => { myScore = maxScore; console.log("instant win opponent disconnect") - const data = { - myScore: myScore, - opScore: hisScore, - opName: opName, - opRank: opRank, - }; + // const data = { + // myScore: myScore, + // opScore: hisScore, + // opName: opName, + // opRank: opRank, + // }; - await api.post('/win', data); + // await api.post('/win', data); console.log("after request1") await api.post('/status', {status: 1}); console.log("after request2") @@ -152,7 +152,7 @@ socket.on('pong:win', async () => { running = false; socket.emit('pong:disconnect', {id: myId}); console.log("before reload") - window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong"); + // window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong"); // window.location.reload(); return ; // console.log("send all ?? win"); @@ -468,6 +468,7 @@ async function draw(timestamp: number) } if (myScore === maxScore || hisScore === maxScore) { + console.log("maxScore!!!!") const data = { myScore: myScore, opScore: hisScore, @@ -485,8 +486,9 @@ async function draw(timestamp: number) } else { - // await api.post('/loss', data); - // await api.post('/status', {status: 1}); + await api.post('/loss', data); + await api.post('/status', {status: 1}); + socket.emit('pong:disconnect', {id: myId}); //disconnect ? console.log("send loose"); } @@ -604,7 +606,9 @@ async function draw(timestamp: number) } if (ballX > canvas.width) { - console.log("win point") + // if (ballX > canvas.width * 2) + // socket.emit + // console.log("win point") // if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius) // { // console.log('true hehe'); From 660088fb7471b3145b21b317245e1d724f74cccc Mon Sep 17 00:00:00 2001 From: Little Dipper Date: Wed, 21 Jun 2023 02:49:02 +0200 Subject: [PATCH 07/13] button --- containers/react/src/styles/field.css | 38 +++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/containers/react/src/styles/field.css b/containers/react/src/styles/field.css index 27f45d32..07beeba9 100644 --- a/containers/react/src/styles/field.css +++ b/containers/react/src/styles/field.css @@ -1,16 +1,21 @@ .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; color: white; - display: block; + /* display: block; */ margin: auto; margin-top: 30vh; - padding: 2vh 5vw; + padding: 2vh 4vw; height: 10vh; width: 20vw; - font-size: 300%; + font-size: 250%; + text-align: center; } + .field { background-color: rgb(249, 249, 249); /* border-radius: 5vh; */ @@ -22,7 +27,7 @@ height: 80%; width: 80%; /* font-size: 300%; */ - } +} .clicked{ /* justify-content: center; */ @@ -40,6 +45,29 @@ /* padding-top: 25; */ /* padding-top: 177.77% */ } +@media screen and (max-width: 900px){ + .playButton{ + font-size: 200%; + } +} + +@media screen and (max-width: 700px){ + .playButton{ + font-size: 150%; + } +} + +@media screen and (max-width: 530px){ + .playButton{ + font-size: 100%; + } +} + +@media screen and (max-width: 350px){ + .playButton{ + font-size: 50%; + } +} #myCanvas { background-color: rgb(124, 47, 47); From b8692d064c81e51aa9e0248e8c1ba9d47d2310ac Mon Sep 17 00:00:00 2001 From: Little Dipper Date: Wed, 21 Jun 2023 03:45:13 +0200 Subject: [PATCH 08/13] ajout bouton private/public --- .../react/src/components/Messages/ModalSetting.tsx | 9 ++++++++- containers/react/src/styles/Messages.css | 12 ++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/containers/react/src/components/Messages/ModalSetting.tsx b/containers/react/src/components/Messages/ModalSetting.tsx index d0137544..c925a8e9 100644 --- a/containers/react/src/components/Messages/ModalSetting.tsx +++ b/containers/react/src/components/Messages/ModalSetting.tsx @@ -38,6 +38,9 @@ const ModalSetting = ({handleClose, convId}: ModalSettingProps) => { const [selectedUser, setSelectedUser] = useState(""); const [newName, setNewName] = useState(""); const [newPassword, setNewPassword] = useState(""); + const [privateConv, setPrivateConv] = useState(false); + const dark = () => setPrivateConv(true); + const light = () => setPrivateConv(false); useEffect(()=> { @@ -175,7 +178,11 @@ const ModalSetting = ({handleClose, convId}: ModalSettingProps) => { {/* First selection */}
    -

    Private

    +
    + Public + Private +
    + {/*

    Private

    */}

    Password

    diff --git a/containers/react/src/styles/Messages.css b/containers/react/src/styles/Messages.css index 88a6d3d3..86ef6726 100644 --- a/containers/react/src/styles/Messages.css +++ b/containers/react/src/styles/Messages.css @@ -204,6 +204,18 @@ p { margin: 1%; } +.darkSubmit{ + display: inline-block; + color: white; + background-color: #282155; + border-radius: 10px; + padding: 5px; + font-size: 1.2rem; + text-decoration: none; + font-weight:lighter; + margin: 1%; +} + .div_submit { flex-direction: row; align-items: center; From 7ae25c68ba236c4d7cca0afe2c6fd5449c955ea7 Mon Sep 17 00:00:00 2001 From: Little Dipper Date: Wed, 21 Jun 2023 05:53:47 +0200 Subject: [PATCH 09/13] success --- containers/react/src/components/Header.tsx | 20 ++++++++++++++++++++ containers/react/src/styles/Header.css | 10 ++++++++++ 2 files changed, 30 insertions(+) diff --git a/containers/react/src/components/Header.tsx b/containers/react/src/components/Header.tsx index 05ab38db..9a607f9a 100644 --- a/containers/react/src/components/Header.tsx +++ b/containers/react/src/components/Header.tsx @@ -4,16 +4,22 @@ import {Link} from 'react-router-dom'; import DefaultPicture from '../assets/profile.jpg' import { motion, AnimatePresence } from 'framer-motion' import Modal from './Sidebar/Modal.tsx'; +import YellowAlert from './Alert/YellowAlert.tsx'; import '../styles/Header.css'; import api from '../script/axiosApi.tsx'; +import { MdQrCodeScanner } from 'react-icons/md'; +import { GiWingedSword, GiCrownedSkull } from 'react-icons/gi'; + function Header() { // const [sidebar, setSidebar] = useState(false); // const showSidebar = () => setSidebar(!sidebar); const [modalOpen, setModalOpen] = useState(false); const close = () => setModalOpen(false); const open = () => setModalOpen(true); + + const [success, setSuccess] = useState([]); const [profilePicture, setProfilePicture] = useState(''); @@ -23,6 +29,8 @@ function Header() { const user = await api.get("/profile"); const pic = await api.post("/getPicture", {username: user.data.username}) setProfilePicture(pic.data); + // console.log("test ===", user.data) + setSuccess(user.data); // console.log(`profile pic222= ${pic.data}`) } catch (error) { console.error('Error fetching profile picture:', error); @@ -45,6 +53,18 @@ function Header() {
    + + {success.otp_verified ? ( + + ):("")} + {success.win >= 2 ? ( + + ):("")} + + {success.win >= 5 ? ( + + ):("")} +
    diff --git a/containers/react/src/styles/Header.css b/containers/react/src/styles/Header.css index 81f24e09..c3f1732a 100644 --- a/containers/react/src/styles/Header.css +++ b/containers/react/src/styles/Header.css @@ -89,6 +89,16 @@ span { border-radius: 50%; } +.success { + height: 25px; + width: 25px; + /* border: solid; */ + margin-top: 2.5vh; + margin-left: 1vh; + /* border-color: black; */ + /* border-radius: 50%; */ +} + .header-pic{ text-align: end; /* id: right; */ From 9cb31f88defebb884ee1ac3ea0780a5aebfe20de Mon Sep 17 00:00:00 2001 From: kinou-p Date: Wed, 21 Jun 2023 08:16:09 +0200 Subject: [PATCH 10/13] env to localhost --- .env | 6 +++--- containers/react/.env | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.env b/.env index 4b96a475..aae0c767 100644 --- a/.env +++ b/.env @@ -14,9 +14,9 @@ NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf" # BASE_URL=http://localhost -BASE_URL=92.143.191.152 -REACT_APP_BASE_URL=92.143.191.152 -REDIRECT_URI=http://92.143.191.152/api/auth/login +BASE_URL=localhost +REACT_APP_BASE_URL=localhost +REDIRECT_URI=http://localhost/api/auth/login #postgres var # POSTGRES_HOST=127.0.0.1 # DB_TYPE=postgres diff --git a/containers/react/.env b/containers/react/.env index 422ef8df..35542322 100644 --- a/containers/react/.env +++ b/containers/react/.env @@ -1,4 +1,4 @@ -REACT_APP_BASE_URL=92.143.191.152 +REACT_APP_BASE_URL=localhost REACT_APP_API_SECRET=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 REACT_APP_CLIENT_UID=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41 # REACT_APP_BASE_URL=92.143.191.152 From 6bf99bd55e56bdfb1675abe4bf5442ce790fe7c2 Mon Sep 17 00:00:00 2001 From: Little Dipper Date: Wed, 21 Jun 2023 20:59:26 +0200 Subject: [PATCH 11/13] success on profile add input for time mute modif change picture button --- .../src/components/Messages/ModalSetting.tsx | 13 ++++-- containers/react/src/pages/Home.tsx | 44 ++++++++++++++++--- containers/react/src/styles/App.css | 2 +- containers/react/src/styles/Header.css | 9 ++-- containers/react/src/styles/Messages.css | 11 ++++- containers/react/src/styles/Profile.css | 7 ++- containers/react/src/styles/Win_Loss.css | 2 +- 7 files changed, 71 insertions(+), 17 deletions(-) diff --git a/containers/react/src/components/Messages/ModalSetting.tsx b/containers/react/src/components/Messages/ModalSetting.tsx index c925a8e9..3b73b59b 100644 --- a/containers/react/src/components/Messages/ModalSetting.tsx +++ b/containers/react/src/components/Messages/ModalSetting.tsx @@ -41,6 +41,10 @@ const ModalSetting = ({handleClose, convId}: ModalSettingProps) => { const [privateConv, setPrivateConv] = useState(false); const dark = () => setPrivateConv(true); const light = () => setPrivateConv(false); + const [mute, setMute] = useState(false); + const darkMute = () => setMute(false); + const lightMute = () => setMute(true); + useEffect(()=> { @@ -186,11 +190,11 @@ const ModalSetting = ({handleClose, convId}: ModalSettingProps) => {

    Password

    - {password ? ( + {password || privateConv ? ( setNewPassword(e.target.value)} onKeyDown={handlePassword} - type="text" + type="password" className="in" placeholder="Password"/> ): @@ -236,11 +240,14 @@ const ModalSetting = ({handleClose, convId}: ModalSettingProps) => {
    Send Ban - Mute + Mute Admin
    + {mute ? ( + + ):("")} diff --git a/containers/react/src/pages/Home.tsx b/containers/react/src/pages/Home.tsx index 4e59a416..9bb31121 100644 --- a/containers/react/src/pages/Home.tsx +++ b/containers/react/src/pages/Home.tsx @@ -21,6 +21,9 @@ import { motion, AnimatePresence } from 'framer-motion' import { Link } from "react-router-dom"; import ModalEdit from "../components/Profile/EditName.tsx"; import {AiOutlineHistory} from 'react-icons/ai' +import { MdQrCodeScanner, MdOutlinePhotoLibrary } from 'react-icons/md'; +import { GiWingedSword, GiCrownedSkull } from 'react-icons/gi'; + // import { Link } from "react-router-dom"; // import {UserProfile} from "../DataBase/DataUserProfile"; // import axios from "axios"; @@ -186,14 +189,18 @@ function Profile () { {modalOpen === true ? : } + {modalOpen === true ? ("") : ( + <> + + + + )} -
    - - + {/*
    */} {/* */} {/* */} -
    + {/*
    */}
    ) : ( <> @@ -212,13 +219,40 @@ function Profile () { function Home () { const [move, setmove ] = useState(false); + const [user, setUser] = useState([]); + useEffect(() => { + const fetchSuccess = async () => { + try { + const tmpUser = await api.get("/profile"); + setUser(tmpUser.data); + } + catch (error) + { + console.log(error); + } + }; + fetchSuccess(); + }) + return ( +
    + {/* {user.otp_verified ? ( */} + + {/* ):("")} */} + {/* {user.win >= 2 ? ( */} + + {/* ):("")} */} + + {/* {user.win >= 5 ? ( */} + + {/* ):("")} */} +
    - diff --git a/containers/react/src/styles/App.css b/containers/react/src/styles/App.css index d2a7c169..d4d7c8c6 100644 --- a/containers/react/src/styles/App.css +++ b/containers/react/src/styles/App.css @@ -9,7 +9,7 @@ input.qr{ width: 20%; border-radius: 5px; - background-color: rgb(66, 66, 66); + background-color: rgb(0, 0, 0); margin : 1%; color:white; } diff --git a/containers/react/src/styles/Header.css b/containers/react/src/styles/Header.css index c3f1732a..55a965e2 100644 --- a/containers/react/src/styles/Header.css +++ b/containers/react/src/styles/Header.css @@ -90,11 +90,12 @@ span { } .success { - height: 25px; - width: 25px; + height: 2%; + width: 2%; /* border: solid; */ - margin-top: 2.5vh; - margin-left: 1vh; + margin-top: 1%; + margin: 3vh; + /* margin-bottom: -12vh; */ /* border-color: black; */ /* border-radius: 50%; */ } diff --git a/containers/react/src/styles/Messages.css b/containers/react/src/styles/Messages.css index 86ef6726..39c457fc 100644 --- a/containers/react/src/styles/Messages.css +++ b/containers/react/src/styles/Messages.css @@ -310,7 +310,7 @@ p { .settingSecondPart{ margin-top: 10%; - margin-left: 10%; + margin-left: 5%; /* margin-left: 20%; */ } @@ -329,6 +329,15 @@ input.in{ width: 70%; } +input.in_howLong{ + margin-top: 14.5%; + margin-left: 0px; + background-color: black; + color: white; + border-radius: 12px; + width: 15%; +} + .mdp{ background-color : black; border-radius: 8px; diff --git a/containers/react/src/styles/Profile.css b/containers/react/src/styles/Profile.css index 6d41023c..9749e86e 100644 --- a/containers/react/src/styles/Profile.css +++ b/containers/react/src/styles/Profile.css @@ -61,12 +61,15 @@ .page { text-align: center; + overflow-y: scroll; /* height: 50vh; */ /* width: 50vh; */ /* background-color: black; */ } .profile { + align-items: center; + text-align: center; flex-direction: row; color: white; } @@ -79,7 +82,7 @@ border-color: red; /* border-image: linear-gradient(90deg, #5843e4, #5a0760); */ - margin-top: 20px; + /* margin-top: 20px; */ } .home{ @@ -106,7 +109,7 @@ .div_history { flex-direction: row; align-items: center; - margin-top: -80px; + /* margin-top: -80px; */ } .edit_name { diff --git a/containers/react/src/styles/Win_Loss.css b/containers/react/src/styles/Win_Loss.css index fdb3df72..1677e6bd 100644 --- a/containers/react/src/styles/Win_Loss.css +++ b/containers/react/src/styles/Win_Loss.css @@ -2,7 +2,7 @@ /* display: flex; */ /* flex-direction: column; */ /* background-color: red; */ - height: 70vh; + height: 60vh; /* padding: 15px; */ /* overflow: scroll; */ From f04ea2557409f391ebad4494907b1889429e9e48 Mon Sep 17 00:00:00 2001 From: Little Dipper Date: Thu, 22 Jun 2023 00:31:59 +0200 Subject: [PATCH 12/13] remise des success a 0 ajout de l'interaction --- .../src/components/Alert/YellowAlert.tsx | 26 ++++++++-- containers/react/src/components/Header.tsx | 13 +---- containers/react/src/pages/Home.tsx | 47 ++++++++++++++----- containers/react/src/styles/Messages.css | 6 +++ 4 files changed, 64 insertions(+), 28 deletions(-) diff --git a/containers/react/src/components/Alert/YellowAlert.tsx b/containers/react/src/components/Alert/YellowAlert.tsx index 1537dd54..eab74971 100644 --- a/containers/react/src/components/Alert/YellowAlert.tsx +++ b/containers/react/src/components/Alert/YellowAlert.tsx @@ -3,6 +3,8 @@ import { motion } from 'framer-motion' import { GrTrophy } from "react-icons/gr"; import '../../styles/Messages.css' import React from "react"; +import { MdQrCodeScanner } from "react-icons/md"; +import { GiCrownedSkull, GiWingedSword } from "react-icons/gi"; const dropIn = { hidden: { @@ -18,10 +20,11 @@ const dropIn = { interface AlertProps { handleClose: Function, - text: string + text: string, + icon: number } -function YellowAlert ({handleClose, text}: AlertProps) { +function YellowAlert ({handleClose, text, icon}: AlertProps) { return( - -

    {text}

    + + {icon === 0 ? ( + + ):("")} + {icon === 1 ? ( + + ):("")} + + {icon === 2 ? ( + + ):("")} + + {icon === 3 ? ( + + ):("")} + +
    {text}
    {setTimeout(handleClose, 3000)}
    diff --git a/containers/react/src/components/Header.tsx b/containers/react/src/components/Header.tsx index 9a607f9a..27ce65a3 100644 --- a/containers/react/src/components/Header.tsx +++ b/containers/react/src/components/Header.tsx @@ -53,18 +53,7 @@ function Header() {
    - - {success.otp_verified ? ( - - ):("")} - {success.win >= 2 ? ( - - ):("")} - - {success.win >= 5 ? ( - - ):("")} - +
    diff --git a/containers/react/src/pages/Home.tsx b/containers/react/src/pages/Home.tsx index 9bb31121..ecfbc71e 100644 --- a/containers/react/src/pages/Home.tsx +++ b/containers/react/src/pages/Home.tsx @@ -36,6 +36,7 @@ import { IoCloseCircleOutline } from "react-icons/io5"; import React, { useState, useEffect, useRef, ChangeEventHandler } from "react"; import { useParams } from 'react-router-dom'; import {User, Conv} from "../../interfaces.tsx" +import YellowAlert from '../components/Alert/YellowAlert.tsx'; // axios.get("http://localhost/api") // .then((response) => { // response = response.json() @@ -185,8 +186,8 @@ function Profile () { {mine ? (
    - (modalOpen ? close() : open())}> - + + (modalOpen ? close() : open())}> {modalOpen === true ? : } {modalOpen === true ? ("") : ( @@ -220,6 +221,15 @@ function Profile () { function Home () { const [move, setmove ] = useState(false); const [user, setUser] = useState([]); + + const [successQr, setSuccessQr] = useState(false); + const [successSword, setSuccessSword] = useState(false); + const [successCrown, setSuccessCrown] = useState(false); + const closeQr = () => setSuccessQr(false); + const closeSword = () => setSuccessSword(false); + const closeCrown = () => setSuccessCrown(false); + + useEffect(() => { const fetchSuccess = async () => { try { @@ -240,16 +250,16 @@ function Home () { animate={{opacity: 1}} exit={{opacity: -1}}>
    - {/* {user.otp_verified ? ( */} - - {/* ):("")} */} - {/* {user.win >= 2 ? ( */} - - {/* ):("")} */} + {user.otp_verified ? ( + setSuccessQr(true)}/> + ):("")} + {user.win >= 2 ? ( + setSuccessSword(true)}/> + ):("")} - {/* {user.win >= 5 ? ( */} - - {/* ):("")} */} + {user.win >= 5 ? ( + setSuccessCrown(true)}/> + ):("")}
    setmove(!move)}> Match History - + null}> + {successQr ? ( + + ) : ("")} + + {successCrown ? ( + + ) : ("")} + + {successSword ? ( + + ) : ("")} + + ) } diff --git a/containers/react/src/styles/Messages.css b/containers/react/src/styles/Messages.css index 39c457fc..81d05423 100644 --- a/containers/react/src/styles/Messages.css +++ b/containers/react/src/styles/Messages.css @@ -288,6 +288,12 @@ p { background-color: rgba(212, 175, 55, 0.7); font-size: 25px; color: rgba(255, 255, 255, 1); + flex-wrap: wrap; +} + +.yellowAlert::p { + overflow-wrap: break-word; + max-width: 1000px; } .modalSetting{ From 78c3c19de83bcbb860057f485b1ae288062d99d3 Mon Sep 17 00:00:00 2001 From: Alexandre POMMIER Date: Fri, 23 Jun 2023 15:47:57 +0200 Subject: [PATCH 13/13] project work in 42 --- .env | 10 ++-- conf/nginx.conf | 18 +++++- containers/api/src/config/config.service.ts | 4 +- containers/api/src/model/chat.entity.ts | 4 +- containers/pong/src/pong/pong.gateway.ts | 9 +-- containers/react/.env | 2 +- containers/react/package.json | 2 +- .../react/src/components/Game/Ranking.tsx | 9 --- .../react/src/components/Messages/Chats.tsx | 9 +-- .../react/src/components/Messages/Modal.tsx | 2 - containers/react/src/pages/Field.tsx | 55 +------------------ containers/react/src/pages/canvas.tsx | 20 +------ 12 files changed, 35 insertions(+), 109 deletions(-) diff --git a/.env b/.env index aae0c767..6449f712 100644 --- a/.env +++ b/.env @@ -14,22 +14,22 @@ NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf" # BASE_URL=http://localhost -BASE_URL=localhost -REACT_APP_BASE_URL=localhost -REDIRECT_URI=http://localhost/api/auth/login +BASE_URL=localhost:8080 +REACT_APP_BASE_URL=localhost:8080 +REDIRECT_URI=http://localhost:8080/api/auth/login #postgres var # POSTGRES_HOST=127.0.0.1 # DB_TYPE=postgres POSTGRES_HOST=postgresql POSTGRES_USER=postgres -POSTGRES_PASSWORD=pass +POSTGRES_PASSWORD=postgres POSTGRES_DATABASE=postgres MODE=DEV #port API_PORT=3000 # REACT_PORT=3000 (current = 8080) -NGINX_PORT=80 +NGINX_PORT=8080 PONG_PORT=4000 CHAT_PORT=4001 POSTGRES_PORT=5432 diff --git a/conf/nginx.conf b/conf/nginx.conf index 8af41775..d3040731 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -3,14 +3,14 @@ server { # listen 80 ssl; # listen 443 ssl; # listen ${NGINX_PORT}; - listen 80; + listen 8080; location /{ proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; - proxy_pass http://react_app:8080; + proxy_pass http://react_app:8001; } location /api { @@ -20,4 +20,18 @@ server { proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://api:3000/api; } + + location /socket { + # Forward requests to socket server running on port 4001 + if ($request_uri ~ ^/socket/4001) { + proxy_pass http://chat:4001; + break; + } + + # Forward requests to socket server running on port 4000 + if ($request_uri ~ ^/socket/4000) { + proxy_pass http://pong:4000; + break; + } + } } \ No newline at end of file diff --git a/containers/api/src/config/config.service.ts b/containers/api/src/config/config.service.ts index efb443aa..5ac28d33 100644 --- a/containers/api/src/config/config.service.ts +++ b/containers/api/src/config/config.service.ts @@ -6,7 +6,7 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/09 14:53:49 by apommier #+# #+# */ -/* Updated: 2023/06/12 14:51:44 by apommier ### ########.fr */ +/* Updated: 2023/06/22 20:42:32 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,7 +17,7 @@ export const getTypeOrmConfig = (): TypeOrmModuleOptions => ({ host: process.env.POSTGRES_HOST || 'postgresql', port: parseInt(process.env.POSTGRES_PORT, 10) || 5432, username: process.env.POSTGRES_USER || 'postgres', - password: process.env.POSTGRES_PASSWORD || 'pass', + password: process.env.POSTGRES_PASSWORD || 'postgres', database: process.env.POSTGRES_DATABASE || 'postgres', entities: ["dist/**/*.entity.js"], // entities: [join(__dirname, '**', '*.entity.{ts,js}')] diff --git a/containers/api/src/model/chat.entity.ts b/containers/api/src/model/chat.entity.ts index b81950d6..84a72306 100644 --- a/containers/api/src/model/chat.entity.ts +++ b/containers/api/src/model/chat.entity.ts @@ -6,12 +6,12 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/17 01:00:20 by apommier #+# #+# */ -/* Updated: 2023/06/17 01:31:29 by apommier ### ########.fr */ +/* Updated: 2023/06/23 15:18:19 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, BaseEntity } from 'typeorm'; - + @Entity() export class Conv{ @PrimaryGeneratedColumn() diff --git a/containers/pong/src/pong/pong.gateway.ts b/containers/pong/src/pong/pong.gateway.ts index 42e1b648..d5a8649f 100644 --- a/containers/pong/src/pong/pong.gateway.ts +++ b/containers/pong/src/pong/pong.gateway.ts @@ -6,7 +6,7 @@ /* By: apommier +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/19 15:18:38 by apommier #+# #+# */ -/* Updated: 2023/06/21 00:59:39 by apommier ### ########.fr */ +/* Updated: 2023/06/23 15:19:12 by apommier ### ########.fr */ /* */ /* ************************************************************************** */ @@ -50,14 +50,7 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa handleDisconnect(client: Socket) { - // console.log(`Client disconnected: ${client.id}`); console.log(`Normal disconnected: ${client.id}`); - // this.waitingClients.delete(client); - // this.waitingClients.forEach((waitingClient) => { - // if (waitingClient.client === client) { - // this.waitingClients.delete(waitingClient); - // }}) - // delete this.clients[client.id]; this.waitingClients.forEach((item) => { if (item.client === client) diff --git a/containers/react/.env b/containers/react/.env index 35542322..d7d79fd5 100644 --- a/containers/react/.env +++ b/containers/react/.env @@ -1,4 +1,4 @@ -REACT_APP_BASE_URL=localhost +REACT_APP_BASE_URL=localhost:8080 REACT_APP_API_SECRET=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 REACT_APP_CLIENT_UID=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41 # REACT_APP_BASE_URL=92.143.191.152 diff --git a/containers/react/package.json b/containers/react/package.json index f0205289..705f72d4 100644 --- a/containers/react/package.json +++ b/containers/react/package.json @@ -22,7 +22,7 @@ "web-vitals": "^2.1.4" }, "scripts": { - "start": "HOST=0.0.0.0 PORT=8080 react-scripts start", + "start": "HOST=0.0.0.0 PORT=8001 react-scripts start", "start:dev": "npm run start --watch", "build": "react-scripts build", "test": "react-scripts test", diff --git a/containers/react/src/components/Game/Ranking.tsx b/containers/react/src/components/Game/Ranking.tsx index 1880abcc..94f417ed 100644 --- a/containers/react/src/components/Game/Ranking.tsx +++ b/containers/react/src/components/Game/Ranking.tsx @@ -43,15 +43,6 @@ function Ranking(){
    {ranking.map((user, index) => ( - // return ( - //
    - //
    - //

    {index + 1}

    - //

    {user.rank}: {user.nickname}

    - //
    - //

    {user.opponent}

    - //
    - // ) ))}
    )} diff --git a/containers/react/src/components/Messages/Chats.tsx b/containers/react/src/components/Messages/Chats.tsx index a971c853..65539f55 100644 --- a/containers/react/src/components/Messages/Chats.tsx +++ b/containers/react/src/components/Messages/Chats.tsx @@ -83,7 +83,7 @@ interface MessageProps { } function Chats(){ - + const [isLoading, setIsLoading] = useState(true); const [conversations, setConversation] = useState([]); const [partyInvite, setPartyInvite] = useState([]); @@ -94,7 +94,7 @@ function Chats(){ const [messages, setMessage] = useState([]); const [newMessages, setNewMessage] = useState(""); const [incomingMessage, setIncomingMessage] = useState(); - + // let socket: Socket; const socket = useRef(null); // const socket = Socket | null @@ -114,8 +114,9 @@ function Chats(){ setPartyInvite(tmpInvite.data); setUser(tmpUser.data); setConversation(convs.data); - // console.log(`connection....`); - socket.current = io('http://' + process.env.REACT_APP_BASE_URL + ':4001', { transports: ['polling'] }); + console.log(`connection....`); + socket.current = io('http://localhost:4001', { transports: ['polling'] }); + console.log(`connection done`); socket.current.emit('connection', {username: tmpUser.data.username}) socket.current.on('message', (data) => { //data should be a message ?) setIncomingMessage(data); diff --git a/containers/react/src/components/Messages/Modal.tsx b/containers/react/src/components/Messages/Modal.tsx index b7eb1d44..c4c58890 100644 --- a/containers/react/src/components/Messages/Modal.tsx +++ b/containers/react/src/components/Messages/Modal.tsx @@ -109,8 +109,6 @@ const Modal = ({handleClose}) => { animate="visible" exit="exit" > - {/*

    New Conversation

    */} - {selectTags.map((selectTag) => (