fix error everywhere fix name, pong private party, blocked effective ?

This commit is contained in:
kinou-p 2023-06-19 22:07:06 +02:00
parent f137b84893
commit 0c04e29cc7
24 changed files with 886 additions and 494 deletions

6
.env
View File

@ -14,9 +14,9 @@
NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf" NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf"
# BASE_URL=http://localhost # BASE_URL=http://localhost
BASE_URL=92.143.191.152 BASE_URL=localhost
REACT_APP_BASE_URL=92.143.191.152 REACT_APP_BASE_URL=localhost
REDIRECT_URI=http://92.143.191.152/api/auth/login REDIRECT_URI=http://localhost/api/auth/login
#postgres var #postgres var
# POSTGRES_HOST=127.0.0.1 # POSTGRES_HOST=127.0.0.1
# DB_TYPE=postgres # DB_TYPE=postgres

View File

@ -6,7 +6,7 @@
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/17 01:00:00 by apommier #+# #+# */ /* Created: 2023/06/17 01:00:00 by apommier #+# #+# */
/* Updated: 2023/06/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 { VerifyOTP } from './users/2fa';
import { ValidateOTP } from './users/2fa'; import { ValidateOTP } from './users/2fa';
import { privateDecrypt } from 'crypto'; import { privateDecrypt } from 'crypto';
import { formatWithOptions } from 'util';
//2fa //2fa
@ -128,6 +129,8 @@ export class AppController {
async newBlocked(@Request() req, @Body() data: any) { async newBlocked(@Request() req, @Body() data: any) {
// return await this.userService.getFriends(req.user.username); // return await this.userService.getFriends(req.user.username);
console.log(`user= ${req.user.username}`) console.log(`user= ${req.user.username}`)
if (data.username === req.user.username)
return (0);
const user = await this.userService.findOne(req.user.username) const user = await this.userService.findOne(req.user.username)
return await this.userService.addBlocked(user, data.username); return await this.userService.addBlocked(user, data.username);
} }
@ -136,6 +139,8 @@ export class AppController {
@Post('/invite') @Post('/invite')
async newInvite(@Request() req, @Body() data: any) { async newInvite(@Request() req, @Body() data: any) {
console.log(`user= ${req.user.username}`) console.log(`user= ${req.user.username}`)
if (data.username === req.user.username)
return (0);
const user = await this.userService.findOne(data.username) const user = await this.userService.findOne(data.username)
if (!user) if (!user)
return (0); return (0);
@ -270,6 +275,44 @@ export class AppController {
return await this.userService.getRanking(); return await this.userService.getRanking();
} }
@UseGuards(JwtAuthGuard)
@Post('/partyInvite')
async partyInvite(@Request() req, @Body() data: any)
{
//find data.username and add invite to list
console.log("data post priv invite=", data);
const user = await this.userService.findOne(data.username);
user.partyInvite = user.partyInvite || [];
user.partyInvite.push({ username: req.user.username, gameId: data.gameId });
console.log("usr === ", user)
await this.userService.save(user);
// user.partyInvite.push(data);
console.log("invite === ", user.partyInvite)
}
@UseGuards(JwtAuthGuard)
@Get('/partyInvite')
async getPartyInvite(@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) @UseGuards(JwtAuthGuard)
@Post('/history') @Post('/history')
async getHistory(@Body() data: any) async getHistory(@Body() data: any)
@ -441,6 +484,13 @@ export class AppController {
return await this.chatService.findAll(); return await this.chatService.findAll();
} }
@UseGuards(JwtAuthGuard)
@Post('/convId')
async getConvById(@Body() data: any) {
return await this.chatService.findConv(data.convId);
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/message') @Post('/message')
async postMessage(@Request() req, @Body() data: any) { async postMessage(@Request() req, @Body() data: any) {
@ -479,12 +529,6 @@ export class AppController {
// res.json(messages); // res.json(messages);
}
@UseGuards(JwtAuthGuard)
@Post('/ban')
async banUser(@Body() data: any) {
return await this.chatService.banUser(data.convId, data.username)
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@ -495,30 +539,48 @@ export class AppController {
return await this.chatService.setName(data.convId, data.name) return await this.chatService.setName(data.convId, data.name)
} }
@UseGuards(JwtAuthGuard)
@Post('/invite')
async inviteUser(@Body() data: any) {
return await this.chatService.inviteUser(data.convId, data.username)
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/password') @Post('/password')
async setPassword(@Body() data: any) { async setPassword(@Body() data: any) {
return await this.chatService.setPassword(data.convId, data.password) return await this.chatService.setPassword(data.convId, data.password)
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/verifyPassword') @Post('/verifyPassword')
async verifyPassword(@Body() data: any) { 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) @UseGuards(JwtAuthGuard)
@Post('/admin') @Post('/admin')
async setAdmin(@Body() data: any) { async setAdmin(@Body() data: any) {
if (!data.username)
return ;
return await this.chatService.setAdmin(data.convId, data.username) return await this.chatService.setAdmin(data.convId, data.username)
} }
@UseGuards(JwtAuthGuard)
@Post('/mute')
async muteUser(@Body() data: any) {
if (!data.username)
return ;
return await this.chatService.muteUser(data.convId, data.username)
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/isAdmin') @Post('/isAdmin')
async isAdmin(@Request() req, @Body() data: any) { async isAdmin(@Request() req, @Body() data: any) {
@ -526,11 +588,6 @@ export class AppController {
return await this.chatService.isAdmin(data.convId, req.user.username) return await this.chatService.isAdmin(data.convId, req.user.username)
} }
@UseGuards(JwtAuthGuard)
@Post('/mute')
async muteUser(@Body() data: any) {
return await this.chatService.muteUser(data.convId, data.username)
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/private') @Post('/private')

View File

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

View File

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

View File

@ -8,15 +8,19 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
@WebSocketServer() @WebSocketServer()
server: Server; server: Server;
private clients: Record<string, Socket> = {}; private clients: Record<string, Socket> = {};
// private clientsNames: Record<string, Socket[]> = {}; // private clientsNames: Record<string, Socket[]> = {};
private clientsNames: Map<string, string[]> = new Map(); private clientsNames: Map<string, string[]> = new Map();
// private games: Map<string, Socket[]> = new Map();// Chat en cours, identifiées par un ID // private games: Map<string, Socket[]> = new Map();// Chat en cours, identifiées par un ID
afterInit(server: Server) afterInit(server: Server)
{ {
console.log('ChatGateway initialized'); console.log('ChatGateway initialized');
} }
handleConnection(client: Socket, ...args: any[]) handleConnection(client: Socket, ...args: any[])
{ {
@ -92,18 +96,12 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
console.log("create") console.log("create")
this.clientsNames.set(payload.username, [client.id]); // Create a new array with the new client as the value this.clientsNames.set(payload.username, [client.id]); // Create a new array with the new client as the value
} }
// let clientLenght = Object.keys(this.clientsNames[payload.username]).length
// const clientArray = this.clientsNames.get(payload.username)
// let clientLenght = clientArray.
// console.log(`lenght= ${clientLenght}`)
// this.clientsNames[payload.username][clientLenght] = this.clients[client.id];
// console.log(`clients: ${Object.keys(this.clientsNames).length}`)
// this.clients[clientId] = client;
//add a new client with socket and name for key
//payload.username
} }
@SubscribeMessage('socket.io')
socketConnect(client: any, payload: any): void {
console.log("/socket.io")
}
// @SubscribeMessage('sendMessage') // @SubscribeMessage('sendMessage')

View File

@ -1,7 +1,26 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* pong.gateway.ts :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 { SubscribeMessage, WebSocketGateway, OnGatewayInit, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';
import { Server, Socket } from 'socket.io'; import { Server, Socket } from 'socket.io';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
//========================================================================================================
//========================================================================================================
// Connection/Disconnection
//========================================================================================================
//========================================================================================================
@WebSocketGateway({ cors: true }) @WebSocketGateway({ cors: true })
export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect { export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
@WebSocketServer() server: Server; @WebSocketServer() server: Server;
@ -31,7 +50,8 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
handleDisconnect(client: Socket) 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.delete(client);
this.waitingClients.forEach((waitingClient) => { this.waitingClients.forEach((waitingClient) => {
if (waitingClient.client === client) { 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}`); 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') @SubscribeMessage('pong:matchmaking')
addMatchmaking(client: Socket, payload: any): void { addMatchmaking(client: Socket, payload: any): void {
@ -91,6 +136,7 @@ addMatchmaking(client: Socket, payload: any): void {
waitingClient.option === payload.option && waitingClient.client !== client waitingClient.option === payload.option && waitingClient.client !== client
); );
if (matchingClients.length > 0) { if (matchingClients.length > 0) {
console.log("Creating new game..."); console.log("Creating new game...");
const players = [matchingClients[0].client, client]; // Add the current client to the players array const players = [matchingClients[0].client, client]; // Add the current client to the players array
@ -117,43 +163,76 @@ addMatchmaking(client: Socket, payload: any): void {
player.emit('pong:gameId', gameId); player.emit('pong:gameId', gameId);
}); });
} }
// console.log(`from: ${client.id}`); // console.log(`from: ${client.id}`);
} }
// @SubscribeMessage('pong:message')
// handleMessage(client: Socket, payload: any): void
// {
// console.log(`from: ${client.id}`);
// console.log(payload);
// const game = this.games.get(payload.gameId);
// const playersIds = game.map(socket => socket.id);
// // const players = Object.keys(game);
// // if (Object.keys(this.clients).length === 2)
// // { //========================================================================================================
// // const clientIds = Object.keys(this.clients); //========================================================================================================
// // console.log(`id of 0= ${clientIds[0]}`); // Private Match
//========================================================================================================
// // payload.ballX //========================================================================================================
// // payload.ballY
// // payload.
// if (clientIds[0] === payload.id) // @SubscribeMessage('pong:invite')
// { // createPrivateGame(client: Socket, payload: any): void {
// // console.log("client 0 true"); // //after invite accepted ?
// if (payload.ballX <= payload.width / 2) // //set the two user in a game ?
// this.clients[clientIds[1]].emit('pong:info', payload);
// } // }
// else if (clientIds[1] === payload.id)
// {
// if (payload.ballX < payload.width / 2) @SubscribeMessage('pong:joinParty')
// this.clients[clientIds[0]].emit('pong:info', payload); joinPrivateParty(client: Socket, payload: any): void {
// // console.log("client 0 true"); console.log(" join PrivateParty")
// }
// // } const game = this.games.get(payload.gameId);
// console.log("END OF HANDLE"); if (game)
// } {
game.push(client);
const playersIds = game.map(socket => socket.id);
this.clients[playersIds[0]].emit('pong:gameId', payload.gameId);
this.clients[playersIds[1]].emit('pong:gameId', payload.gameId);
}
else
{
console.log("emit else")
client.emit("pong:win")
}
// console.log("no game ???")
}
@SubscribeMessage('pong:privateParty')
addPrivateParty(client: Socket, payload: any): void {
console.log("addPrivateParty")
const gameId = uuidv4();
const players = [client];
this.games.set(gameId, players);
console.log("game created private")
client.emit('pong:privateId', gameId);
//create game
//emit private gameId to canvas (don't launch canvas)
}
//========================================================================================================
//========================================================================================================
// In Game
//========================================================================================================
//========================================================================================================
@SubscribeMessage('pong:power') @SubscribeMessage('pong:power')
sendPower(client: Socket, payload: any): void sendPower(client: Socket, payload: any): void
@ -191,29 +270,6 @@ addMatchmaking(client: Socket, payload: any): void {
console.log("END OF HANDLE"); console.log("END OF HANDLE");
} }
// @SubscribeMessage('pong:forced')
// forcedMessage(client: Socket, payload: any): void
// {
// console.log(`from: ${client.id}`);
// console.log(payload);
// if (Object.keys(this.clients).length === 2)
// {
// const clientIds = Object.keys(this.clients);
// console.log(`id of 0= ${clientIds[0]}`);
// if (clientIds[0] === payload.id)
// {
// this.clients[clientIds[1]].emit('pong:info', payload);
// }
// else if (clientIds[1] === payload.id)
// {
// this.clients[clientIds[0]].emit('pong:info', payload);
// }
// }
// console.log("END OF HANDLE");
// }
@SubscribeMessage('pong:forced') @SubscribeMessage('pong:forced')
forcedMessage(client: Socket, payload: any): void forcedMessage(client: Socket, payload: any): void
{ {
@ -236,29 +292,6 @@ addMatchmaking(client: Socket, payload: any): void {
console.log("END OF HANDLE"); console.log("END OF HANDLE");
} }
// @SubscribeMessage('pong:paddle')
// handlePaddle(client: Socket, payload: any): void
// {
// console.log(`from: ${client.id}`);
// console.log(payload);
// if (Object.keys(this.clients).length === 2)
// {
// const clientIds = Object.keys(this.clients);
// console.log(`id of 0= ${clientIds[0]}`);
// if (clientIds[0] === payload.id)
// {
// this.clients[clientIds[1]].emit('pong:paddle', payload);
// }
// else if (clientIds[1] === payload.id)
// {
// this.clients[clientIds[0]].emit('pong:paddle', payload);
// }
// }
// console.log("END OF HANDLE");
// }
@SubscribeMessage('pong:paddle') @SubscribeMessage('pong:paddle')
handlePaddle(client: Socket, payload: any): void handlePaddle(client: Socket, payload: any): void
{ {

View File

@ -1,3 +1,5 @@
# REACT_APP_BASE_URL=localhost 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
# REACT_APP_BASE_URL=192.168.1.19 # REACT_APP_BASE_URL=192.168.1.19

View File

@ -1,12 +1,12 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* Rank.jsx :+: :+: :+: */ /* Rank.tsx :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/09 08:49:24 by apommier #+# #+# */ /* Created: 2023/06/09 08:49:24 by apommier #+# #+# */
/* Updated: 2023/06/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(); fetchProfilePicture();
}) })
// console.log(index);
return ( return (
<div className='rank_elements'> <div className='rank_elements'>
<div> <div >
<p>{index + 1}</p> {/* <p>{(index + 1).toString()}</p> */}
<p>{(index + 1)}</p>
<h4>{user.rank}: {user.nickname} <h4>{user.rank}: {user.nickname}
{profilePicture ? ( {profilePicture ? (
<img className="profilePic" src={`data:image/jpeg;base64,${profilePicture}`} /> <img className="profilePic" src={`data:image/jpeg;base64,${profilePicture}`} />

View File

@ -41,7 +41,7 @@ function Ranking(){
// <h1 className='title'>Ranking</h1> // <h1 className='title'>Ranking</h1>
<div className='scroll'> <div className='scroll'>
{ranking.map((user, index) => ( {ranking.map((user, index) => (
<Rank user={user} index={index}/> <Rank user={user} index={index} key={user.username}/>
// return ( // return (
// <div className='rank_elements'> // <div className='rank_elements'>
// <div> // <div>

View File

@ -6,6 +6,7 @@ import DefaultPic from '../../assets/profile.jpg'
import api from '../../script/axiosApi.tsx'; import api from '../../script/axiosApi.tsx';
import { motion , AnimatePresence} from "framer-motion"; import { motion , AnimatePresence} from "framer-motion";
import Modal from "./Modal.tsx"; import Modal from "./Modal.tsx";
import GameModal from "./GameModal.tsx";
import Message from "./Message.tsx" import Message from "./Message.tsx"
// import Input from "./Input"; // import Input from "./Input";
@ -22,6 +23,7 @@ import GreenAlert from "../Alert/GreenAlert.tsx";
import RedAlert from "../Alert/RedAlert.tsx"; import RedAlert from "../Alert/RedAlert.tsx";
import YellowAlert from "../Alert/YellowAlert"; import YellowAlert from "../Alert/YellowAlert";
import ModalSetting from "./ModalSetting.tsx"; import ModalSetting from "./ModalSetting.tsx";
import PartyInvite from "./PartyInvite.tsx";
const TouchDiv = styled.div` const TouchDiv = styled.div`
@ -75,6 +77,7 @@ function Chats(){
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [conversations, setConversation] = useState([]); const [conversations, setConversation] = useState([]);
const [partyInvite, setPartyInvite] = useState([]);
const [user, setUser] = useState(null); const [user, setUser] = useState(null);
const [currentChat, setCurrentChat] = useState(false); // false is good? const [currentChat, setCurrentChat] = useState(false); // false is good?
const [isAdmin, setIsAdmin] = useState(false); // false is good? const [isAdmin, setIsAdmin] = useState(false); // false is good?
@ -82,7 +85,9 @@ function Chats(){
const [messages, setMessage] = useState([]); const [messages, setMessage] = useState([]);
const [newMessages, setNewMessage] = useState(""); const [newMessages, setNewMessage] = useState("");
const [incomingMessage, setIncomingMessage] = useState(""); const [incomingMessage, setIncomingMessage] = useState("");
const socket = useRef();
let socket;
socket = useRef();
@ -91,24 +96,30 @@ function Chats(){
const getConv = async ()=>{ const getConv = async ()=>{
try{ try{
const convs = await api.get("/conv") const convs = await api.get("/conv")
const tmpInvite = await api.get("/partyInvite")
const tmpUser = await api.get("/profile") const tmpUser = await api.get("/profile")
console.log(convs); console.log(convs);
// console.log("invite data use effect= ", tmpInvite.data);
setPartyInvite(tmpInvite.data);
setUser(tmpUser.data); setUser(tmpUser.data);
setConversation(convs.data); setConversation(convs.data);
socket.current = io('http://' + process.env.REACT_APP_BASE_URL + ':4001'); // console.log(`connection....`);
console.log(`connection....`); socket.current = io('http://' + process.env.REACT_APP_BASE_URL + ':4001', { transports: ['polling'] });
// console.log(`connection done`);
socket.current.emit('connection', {username: tmpUser.data.username}) socket.current.emit('connection', {username: tmpUser.data.username})
socket.current.on('message', (data) => { //data should be a message ? socket.current.on('message', (data) => { //data should be a message ?
console.log(`message received data= ${data.sender}`) // console.log(`message received data= ${data.sender}`)
console.log(`message received data= ${data.convId}`) // console.log(`message received data= ${data.convId}`)
console.log(`message received data= ${data.sender}`) // console.log(`message received data= ${data.sender}`)
console.log(`current chat = ${currentChat}`) // console.log(`current chat = ${currentChat}`)
setIncomingMessage(data); setIncomingMessage(data);
}); });
setIsLoading(false) setIsLoading(false)
} }
catch(err){ catch(err){
console.log("ERRORRRRR")
console.log(err); console.log(err);
} }
}; };
@ -135,8 +146,11 @@ function Chats(){
// console.log(`result1 = ${currentChat.id !== incomingMessage.convId}`) // console.log(`result1 = ${currentChat.id !== incomingMessage.convId}`)
if (currentChat !== null && currentChat.id === incomingMessage.convId) if (currentChat !== null && currentChat.id === incomingMessage.convId)
{ {
console.log("incoming meaasge=",incomingMessage)
setMessage((prev) => [...prev, incomingMessage]); // if (user && !user.blocked.find(incomingMessage.sender))
// setMessage((prev) => [...prev, incomingMessage, key: incomingMessage.id]);
// setMessage((prev) => [...prev, { ...incomingMessage, key: incomingMessage.id }]);
setMessage((prev) => [...prev, incomingMessage]);
} }
} }
updateChat(); updateChat();
@ -169,17 +183,10 @@ function Chats(){
members: null members: null
}; };
try{ 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 res = await api.post('/message', message);
const convMember = await api.post('/member', message); const convMember = await api.post('/member', message);
message.members = convMember.data.members; message.members = convMember.data.members;
console.log(convMember); message.id = res.data.id
// console.log(`currentChat= ${currentChat.id}`)
setMessage([...messages, res.data]); setMessage([...messages, res.data]);
setNewMessage(""); setNewMessage("");
socket.current.emit('sendMessage', message); socket.current.emit('sendMessage', message);
@ -201,13 +208,10 @@ function Chats(){
members: null members: null
}; };
try{ try{
console.log(`id= ${currentChat.id}`)
const res = await api.post('/message', message); const res = await api.post('/message', message);
const convMember = await api.post('/member', message); const convMember = await api.post('/member', message);
message.members = convMember.data.members; message.members = convMember.data.members;
console.log(convMember); message.id = res.data.id
// console.log(`currentChat= ${currentChat.id}`)
setMessage([...messages, res.data]); setMessage([...messages, res.data]);
setNewMessage(""); setNewMessage("");
socket.current.emit('sendMessage', message); socket.current.emit('sendMessage', message);
@ -220,7 +224,7 @@ function Chats(){
const [friend, setFriend] = useState(""); const [friend, setFriend] = useState("");
const [modalOpen, setModalOpen] = useState(false); // const [modalOpen, setModalOpen] = useState(false);
const [addFriend, setAddFriend] = useState(false); const [addFriend, setAddFriend] = useState(false);
const [block, setBlock] = useState(false); const [block, setBlock] = useState(false);
@ -228,8 +232,28 @@ function Chats(){
const [showBlockAlert, setShowBlockAlert] = useState(false); const [showBlockAlert, setShowBlockAlert] = useState(false);
const [setting, setSetting] = useState(false); const [setting, setSetting] = useState(false);
const close = () => setModalOpen(false);
const 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 closeAddFriend = () => setAddFriend(false);
// const closeBlock = () => setBlock(false); // const closeBlock = () => setBlock(false);
const closeSetting = () => setSetting(false); const closeSetting = () => setSetting(false);
@ -404,17 +428,36 @@ function Chats(){
</div> </div>
<div className="messages_box"> <div className="messages_box">
<div className="contact"> <div className="contact">
<UserChat>
<motion.div className="newMessage" <UserChat>
onClick={() => (modalOpen ? close() : open())} <motion.div className="newMessage" onClick={openNewGameModal}>
> <GrAdd />
<GrAdd/> <span>New Game</span>
<span>New Conversation</span> </motion.div>
</motion.div> {newGameModalOpen && <GameModal handleClose={closeNewGameModal} />}
{modalOpen && <Modal modalOpen={modalOpen} handleClose={close}/>} </UserChat>
<UserChat>
<motion.div className="newMessage" onClick={openNewConversationModal}>
<GrAdd />
<span>New Conversation</span>
</motion.div>
{newConversationModalOpen && (
<Modal handleClose={closeNewConversationModal} />
)}
</UserChat>
{/* {partyInvite.map((c) => {
return (
)})
} */}
{partyInvite.map( i =>(
<PartyInvite currentInvite={i}/>
))}
</UserChat>
{conversations.map((c, index ) => { {conversations.map((c, index ) => {
return ( return (
<div key={index} <div key={index}
@ -437,7 +480,7 @@ function Chats(){
<div className="messages"> <div className="messages">
<div className="scroll"> <div className="scroll">
{messages.map(m=>( {messages.map(m=>(
<Message message = {m} own={m.sender === user.username} user={m}/> <Message key={m.id} message= {m} own={m.sender === user.username} user={m}/>
))} ))}
</div> </div>
{/* <Input/> */} {/* <Input/> */}

View File

@ -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 (
<Backdrop>
<motion.div
onClick={(e) => e.stopPropagation()}
className="modal"
variant={dropIn}
initial="hidden"
animate="visible"
exit="exit"
>
<div>
<select value={selectedUser} onChange={handleUserChange}>
<option value="">Select a user</option>
{users.map((user) => (
<option key={user.id} value={user.username}>
{user.username}
</option>
))}
</select>
</div>
<div className="notClicked" id="canvas_container">
{/* <button onClick={handleButtonClick}>Draw on Canvas</button> */}
<div className='checkbox'>
<p><input type="checkbox" value="superpower"/> Super Power </p>
<p><input type="checkbox" value="obstacle"/> Obstacle </p>
<p><input type="checkbox" value="speed"/> Faster and Faster </p>
</div>
<button className="submit" onClick={handleButtonClick} >Play</button>
<button className="submit" onClick={handleClose}>Cancel</button>
</div>
{/* <div className="div_submit">
<button className="submit" onClick={handleCheckButtonClick}>
Invite to play
</button>
</div> */}
</motion.div>
</Backdrop>
);
};
export default GameModal;

View File

@ -1,12 +1,12 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* Message.jsx :+: :+: :+: */ /* Message.tsx :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/01 18:24:46 by apommier #+# #+# */ /* Created: 2023/06/01 18:24:46 by apommier #+# #+# */
/* Updated: 2023/06/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 { useRef } from "react";
// import { useEffect } from "react"; // import { useEffect } from "react";
import '../../styles/Messages.css' import '../../styles/Messages.css'
import React from "react";
const MeStyleP = styled.p` const MeStyleP = styled.p`
background-color: #5843e4; background-color: #5843e4;
@ -29,6 +30,10 @@ const MeStyleP = styled.p`
function MessageMe({message, own}){ function MessageMe({message, own}){
const [profilePicture, setProfilePicture] = useState(''); const [profilePicture, setProfilePicture] = useState('');
const [sender, setSender] = useState();
const [conv, setConv] = useState();
const [user, setUser] = useState();
const scrollRef = useRef(); const scrollRef = useRef();
useEffect(() => { useEffect(() => {
@ -39,9 +44,16 @@ function MessageMe({message, own}){
const fetchProfilePicture = async () => { const fetchProfilePicture = async () => {
try { try {
// const user = await api.get("/profile"); // const user = await api.get("/profile");
const tmpSender = await api.post("/user", {username: message.sender})
const tmpConv = await api.post("/convId", {convId: message.convId})
// const tmpSender = await api.post("/user", {username: message.sender})
const tmpUser = await api.get("/profile")
const pic = await api.post("/getPicture", {username: message.sender}) const pic = await api.post("/getPicture", {username: message.sender})
// console.log(`user naem profile pic222= ${currentUser.username}`) // console.log(`user naem profile pic222= ${currentUser.username}`)
// console.log(` profile pic222= ${pic.data}`) // console.log(` profile pic222= ${pic.data}`)
setConv(tmpConv.data);
setUser(tmpUser.data);
setSender(tmpSender.data);
setProfilePicture(pic.data); setProfilePicture(pic.data);
} catch (error) { } catch (error) {
console.error('Error fetching profile picture:', error); console.error('Error fetching profile picture:', error);
@ -50,23 +62,45 @@ function MessageMe({message, own}){
fetchProfilePicture(); fetchProfilePicture();
}, []) }, [])
const handleButtonClick = () => {
if (!sender)
return;
let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${sender.username}`;
// console.log("path= ", path)
// history(path, { replace: true });
// window.location.replace(path);
window.history.pushState({}, 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 ( return (
<div className={own ? "meMessage" : "youMessage"} ref={scrollRef}> <div className={own ? "meMessage" : "youMessage"} ref={scrollRef}>
<div> <div>
{/* <img className="messageInfo" src={DefaultPic} alt="profile" />
*/}
{profilePicture ? ( {profilePicture ? (
<img className="messageInfo" src={`data:image/jpeg;base64,${profilePicture}`} /> <img className="messageInfo" onClick={() => handleButtonClick()} src={`data:image/jpeg;base64,${profilePicture}`} />
) : ( ) : (
<img className="messageInfo" src={DefaultPicture} alt="Default Profile Picture" /> <img className="messageInfo" onClick={() => handleButtonClick()} src={DefaultPicture} alt="Default Profile Picture" />
)} )}
</div> </div>
{/* <div className="usernameMesage">{message.senderNickname}</div> */} {/* <div className="usernameMesage">{message.senderNickname}</div> */}
<div className="usernameMesage">{message.sender}</div> {sender ? (
<div className="usernameMesage">{sender.nickname}</div>
): ""}
<div className="messageContent"> <div className="messageContent">
<MeStyleP>{message.text}</MeStyleP> <MeStyleP>{message.text}</MeStyleP>
</div> </div>
</div> </div>
) )
} }

View File

@ -147,7 +147,7 @@ const Modal = ({handleClose}) => {
> >
<option value="">Select an option</option> <option value="">Select an option</option>
{convs.map((conv) => ( {convs.map((conv) => (
!(!conv.group || conv.private || (conv.banned && conv.banned.includes(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))) && (
<option key={conv.id} value={conv.id}> <option key={conv.id} value={conv.id}>
{conv.name} {conv.name}
</option> </option>
@ -161,30 +161,6 @@ const Modal = ({handleClose}) => {
</div> </div>
{/* {selectTags.map((selectTag) => (
<div key={selectTag.id}>
<select
value={selectTag.selectedOption}
onChange={(a) => handleOptionChange(selectTag.id, a.target.value)}
>
<option value="">{
selectTag.selectedOption ? selectTag.selectedOption : "Select an option"
}</option>
{convs.filter((item) => !selectTags.some((tag) => tag.selectedOption === item.name)).map((item, index) => (
<option key={index} value={item.name}>
{item.name}
</option>
))}
</select>
</div>
))} */}
{/* <div>
<GrAdd onClick={addNewSelectedTag}/>
</div> */}
</motion.div> </motion.div>
</Backdrop> </Backdrop>

View File

@ -6,6 +6,7 @@ import { useState, useEffect } from "react";
import { GrAdd } from "react-icons/gr"; import { GrAdd } from "react-icons/gr";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import api from "../../script/axiosApi.tsx"; import api from "../../script/axiosApi.tsx";
import React from "react";
const dropIn = { const dropIn = {
@ -114,6 +115,9 @@ const ModalSetting = ({handleClose, convId}) => {
const handleBan = () => { const handleBan = () => {
// console.log("ban option= ", selectedUser) // console.log("ban option= ", selectedUser)
try{ try{
// console.log("user select=", selectedUser.length)
if (!selectedUser.length)
return ;
api.post("/ban", {convId: convId, username: selectedUser}) api.post("/ban", {convId: convId, username: selectedUser})
} catch(err) { } catch(err) {
console.log(err); console.log(err);
@ -122,6 +126,8 @@ const ModalSetting = ({handleClose, convId}) => {
}; };
const handleAdmin = () => { const handleAdmin = () => {
if (!selectedUser.length)
return ;
try{ try{
api.post("/admin", {convId: convId, username: selectedUser}) api.post("/admin", {convId: convId, username: selectedUser})
} catch(err) { } catch(err) {
@ -131,6 +137,8 @@ const ModalSetting = ({handleClose, convId}) => {
}; };
const handleMute = () => { const handleMute = () => {
if (!selectedUser.length)
return ;
try{ try{
api.post("/mute", {convId: convId, username: selectedUser}) api.post("/mute", {convId: convId, username: selectedUser})
} catch(err) { } catch(err) {
@ -162,7 +170,7 @@ const ModalSetting = ({handleClose, convId}) => {
{/* First selection */} {/* First selection */}
<div className="settingFirstPart"> <div className="settingFirstPart">
<div> <div>
<p className="checkbox">Private<input class="check"type="checkbox" value="private" onChange={handleCheckPriv}/></p> <p className="checkbox">Private<input className="check"type="checkbox" value="private" onChange={handleCheckPriv}/></p>
<p className="checkbox">Password<input type="checkbox" value="password" checked={password} onChange={handleCheckPass}/> </p> <p className="checkbox">Password<input type="checkbox" value="password" checked={password} onChange={handleCheckPass}/> </p>

View File

@ -1,3 +1,15 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* PartyInvite.tsx :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 { useEffect, useState } from "react";
import api from '../../script/axiosApi.tsx'; import api from '../../script/axiosApi.tsx';
@ -5,6 +17,7 @@ import DefaultPicture from '../../assets/profile.jpg'
import styled from "styled-components"; import styled from "styled-components";
import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx"; import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx";
import React from "react";
const UserChat = styled.div ` const UserChat = styled.div `
padding: 5px; padding: 5px;
@ -25,7 +38,7 @@ const SideP = styled.p`
margin-left: 15px; margin-left: 15px;
` `
export default function Friend({currentUser}) export default function PartyInvite({currentInvite})
{ {
const [profilePicture, setProfilePicture] = useState(''); const [profilePicture, setProfilePicture] = useState('');
const [request, setRequest] = useState(''); //user who invite const [request, setRequest] = useState(''); //user who invite
@ -37,11 +50,11 @@ export default function Friend({currentUser})
try { try {
// const user = await api.get("/profile");\ // const user = await api.get("/profile");\
// const tmpUser = await api.get("/profile") // const tmpUser = await api.get("/profile")
const pic = await api.post("/getPicture", {username: currentUser.username}) const pic = await api.post("/getPicture", {username: currentInvite.username})
const tmpRequest = await api.post("/user", {username: currentUser.username}) const tmpRequest = await api.post("/user", {username: currentInvite.username})
// setUser(tmpUser.data); // setUser(tmpUser.data);
setRequest(tmpRequest.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}`) // console.log(` profile pic222= ${pic.data}`)
setProfilePicture(pic.data); setProfilePicture(pic.data);
} catch (error) { } catch (error) {
@ -60,10 +73,20 @@ export default function Friend({currentUser})
window.location.reload(false); window.location.reload(false);
}; };
const Accept = async (request) => { const Accept = async (request) => {
try{ try{
await api.post("/friend", {username: request.username}) //call canvas ??
setClickEvent(true); // 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) { } catch(err) {
console.log(err); console.log(err);
} }
@ -73,7 +96,8 @@ export default function Friend({currentUser})
const Refuse = async (request) => { const Refuse = async (request) => {
try{ try{
await api.post("/refuseInvite", {username: request.username}) await api.post("/deleteInvite", {username: request.username})
// await api.post("/refuseInvite", {username: request.username})
setClickEvent(true); setClickEvent(true);
} catch(err) { } catch(err) {
console.log(err); console.log(err);
@ -95,12 +119,11 @@ export default function Friend({currentUser})
<img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" /> <img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" />
)} )}
<div className="infoSideBar"> <div className="infoSideBar">
<span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span> <span onClick={() => handleButtonClick(currentInvite)}>{request.nickname}</span>
<RxCheckCircled onClick={() => Accept(request)} color={'green'}/> <RxCheckCircled onClick={() => Accept(request)} color={'green'}/>
<RxCircleBackslash onClick={() => Refuse(request)} color={'red'}/> <RxCircleBackslash onClick={() => Refuse(request)} color={'red'}/>
</div> </div>
</UserChat> </UserChat>
) )
} }

View File

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

View File

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

View File

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

View File

@ -5,6 +5,7 @@ import DefaultPicture from '../../assets/profile.jpg'
import styled from "styled-components"; import styled from "styled-components";
import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx"; import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx";
import React from "react";
const UserChat = styled.div ` const UserChat = styled.div `
padding: 5px; padding: 5px;

View File

@ -5,6 +5,7 @@ import queryString from 'query-string';
import '../styles/field.css'; import '../styles/field.css';
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import React from 'react';
// import { withRouter } from 'react-router-dom'; // import { withRouter } from 'react-router-dom';
@ -16,7 +17,8 @@ function Field()
console.log("launch canva hehe") console.log("launch canva hehe")
let Modifiers = 0; let Modifiers = 0;
let info;
if (queryParams.superpower === 'true') { if (queryParams.superpower === 'true') {
Modifiers += 1; Modifiers += 1;
} }
@ -28,15 +30,23 @@ function Field()
if (queryParams.speed === 'true') { if (queryParams.speed === 'true') {
Modifiers += 4; Modifiers += 4;
} }
// console.log(`modifiers= ${Modifiers}`)
// DrawCanvas(Modifiers); info = {
// return () => { privateParty: false,
// console.log("000000000000000000000000000000000") }
// // socketRef.current.disconnect(); 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, info);
const cleanup = DrawCanvas(Modifiers);
return () => { return () => {
console.log("Cleanup"); console.log("Cleanup");

View File

@ -1,12 +1,12 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* Home.jsx :+: :+: :+: */ /* Home.tsx :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/09 08:19:04 by apommier #+# #+# */ /* Created: 2023/06/09 08:19:04 by apommier #+# #+# */
/* Updated: 2023/06/09 08:19:05 by apommier ### ########.fr */ /* Updated: 2023/06/19 20:27:00 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -139,10 +139,11 @@ function Profile () {
</Link> </Link>
</motion.div> </motion.div>
<div> <div className="file-upload-container">
<input type="file" accept="image/*" onChange={handleFileChange} /> <label htmlFor="file-input" className="file-label">Choose File</label>
<button onClick={handleUpload}>Upload</button> <input type="file" id="file-input" className="file-input" accept="image/*" onChange={handleFileChange} />
</div> <button onClick={handleUpload} className="upload-button">Upload</button>
</div>
</div> </div>
) : ( ) : (
<></> <></>

View File

@ -15,12 +15,15 @@ function Login42()
const data = { const data = {
grant_type: 'authorization_code', grant_type: 'authorization_code',
client_id: 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41', // client_id: 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41',
client_secret: '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', // client_secret: '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',
client_id: process.env.REACT_APP_CLIENT_UID,
client_secret: process.env.REACT_APP_API_SECRET,
code: code, code: code,
redirect_uri: 'http://' + process.env.REACT_APP_BASE_URL + '/login42', redirect_uri: 'http://' + process.env.REACT_APP_BASE_URL + '/login42',
}; };
axios.post('https://api.intra.42.fr/oauth/token', data) axios.post('https://api.intra.42.fr/oauth/token', data)
.then(response => { .then(response => {
// handle success response // handle success response

View File

@ -8,9 +8,7 @@ import io from 'socket.io-client';
// const socket = io('http://86.209.110.20:4000'); // const socket = io('http://86.209.110.20:4000');
// const socket = io('http://172.29.113.91:4000'); // const socket = io('http://172.29.113.91:4000');
function DrawCanvas(option) { function DrawCanvas(option: number, gameParam) {
console.log(`option= ${option}`); console.log(`option= ${option}`);
const superpowerModifier = option & 1; // Retrieves the superpower modifier const superpowerModifier = option & 1; // Retrieves the superpower modifier
@ -26,6 +24,26 @@ function DrawCanvas(option) {
// const socketRef = useRef(null); // const socketRef = useRef(null);
// socketRef.current = io('http://localhost:4000'); // socketRef.current = io('http://localhost:4000');
const socket = io('http://' + process.env.REACT_APP_BASE_URL + ':4000'); const socket = io('http://' + process.env.REACT_APP_BASE_URL + ':4000');
function launchGame()
{
if (!gameParam.privateParty)
{
console.log("laucnh matchmaking")
matchmaking();
}
else if (!gameParam.gameId)
{
console.log("laucnh private")
privateParty();
}
else
{
console.log("join private")
joinPrivateParty();
}
}
// const socket = socketRef.current // const socket = socketRef.current
console.log("start function"); console.log("start function");
@ -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.emit('pong:matchmaking', info);
} }
// socket.on('pong:gameId', (data) => { function privateParty()
// console.log("gameId received") {
// gameId = data; console.log(`id private party= ${myId}`)
// // api.get('/profile'); const info = {
// 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 = {
id: myId, id: myId,
name: myName, option: option,
gameId: gameId, };
rank: opRank, socket.emit('pong:privateParty', info);
}; }
console.log("emit to name");
socket.emit('pong:name', info);
} catch (error) {
console.log(error);
// Handle error here
return;
}
});
socket.on('pong:name', (data) => { function joinPrivateParty()
opName = data; {
console.log(`opponent Name= ${opName}`) console.log(`id private party= ${myId}`)
}); const info = {
id: myId,
socket.on('connect', () => { gameId: gameParam.gameId,
console.log('Connected to NestJS server'); option: option,
}); };
socket.emit('pong:joinParty', info);
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 send_info() function send_info()
{ {
@ -248,20 +315,6 @@ function DrawCanvas(option) {
socket.emit('pong:point', info); socket.emit('pong:point', info);
} }
socket.on('pong:point', (data) => {
// hisScore += 1;
console.log("gain point");
// if (vX != 0)
// {
// console.log("up point");
myScore = data.point;
// }
vX = 0;
vY = 0;
ballX = canvas.width / 2;
ballY = canvas.height / 2;
});
function send_paddle_info() function send_paddle_info()
{ {
if (gameId === 0) if (gameId === 0)
@ -307,7 +360,7 @@ function DrawCanvas(option) {
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// Drawer // Drawer
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
@ -348,28 +401,50 @@ function DrawCanvas(option) {
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// Loop // Loop
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
matchmaking();
// while (!gameId) // while (!gameId)
// ; // ;
// Define a function to stop the drawing process // Define a function to stop the drawing process
const stopDrawCanvas = () => { const stopDrawCanvas = async () => {
running = false; running = false;
console.log("stopDrawCanvas 1")
if (gameParam.privateParty && !gameId) //delete invite
{
console.log("stopDrawCanvas2")
try{
// const info = {
// id: myId,
// option: option,
// };
await api.post("deleteInvite", {username: gameParam.username})
}
catch (err){
console.log(err)
}
}
socket.emit('pong:disconnect', {id: myId});
window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong");
// window.location.reload(false);
// Perform any necessary cleanup tasks // Perform any necessary cleanup tasks
// ... // ...
}; };
function draw(timestamp) async function draw(timestamp)
{ {
console.log("turning"); console.log("turning, running= ", running);
if (!running) if (!running)
return ; return ;
if (gameId === 0 ) if (gameId === 0 )
{ {
// console.log("nogameid score= ", myScore);
requestAnimationFrame(draw); requestAnimationFrame(draw);
return ; return ;
} }
@ -383,17 +458,22 @@ function draw(timestamp)
}; };
if (myScore === maxScore) if (myScore === maxScore)
{ {
api.post('/win', data); await api.post('/win', data);
api.post('/status', {status: 1}); await api.post('/status', {status: 1});
console.log("send win"); //disconnect ?
socket.emit('pong:disconnect', {id: myId});
console.log("send all ?? win");
} }
else else
{ {
api.post('/loss', data); // await api.post('/loss', data);
api.post('/status', {status: 1}); // await api.post('/status', {status: 1});
//disconnect ?
console.log("send loose"); console.log("send loose");
} }
window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong"); window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong");
// window.location.reload(false);
return ; return ;
} }
@ -415,7 +495,7 @@ function draw(timestamp)
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// Logical Part // Logical Part
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
@ -521,7 +601,7 @@ function draw(timestamp)
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// Listener // Key/Mouse/Finger Listener
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================

View File

@ -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 { .page {
text-align: center; text-align: center;
/* height: 50vh; */ /* height: 50vh; */