Skip to content

Commit

Permalink
friend page finie, stat + historique en cours
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicolas Jaros committed Apr 21, 2023
1 parent 84cb6e8 commit b8e3c7b
Show file tree
Hide file tree
Showing 14 changed files with 218 additions and 111 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IsBoolean, IsNotEmpty, IsString, MaxLength } from "class-validator";
import { IsBoolean, IsNotEmpty, IsString, IsUUID, MaxLength } from "class-validator";

/**
* DTO use for private matchmaking request
Expand All @@ -25,3 +25,7 @@ export class GameInputDTO {
export class SpectatorRequestDTO {
@IsString() @IsNotEmpty() @MaxLength(64) player1_login: string;
}

export class matchHistoryDto {
@IsNotEmpty() @IsUUID() userId: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/

import { ConnectedSocket, MessageBody, OnGatewayConnection, OnGatewayDisconnect, SubscribeMessage, WebSocketGateway, WebSocketServer } from '@nestjs/websockets'; // socket event handling stuff
import { GameInputDTO, PrivateGameRequestDTO, PublicGameRequestDTO, SpectatorRequestDTO } from './game_update_center.dto'; // all the DTO (struct use to verified field of incoming request)
import { GameInputDTO, matchHistoryDto, PrivateGameRequestDTO, PublicGameRequestDTO, SpectatorRequestDTO } from './game_update_center.dto'; // all the DTO (struct use to verified field of incoming request)
import { GameEngineService } from 'src/game_engine/game_engine.service'; // use to acces the gameEngine of the super mode
import { PongEngineService } from 'src/pong_engine/pong_engine.service'; // use to acces the gameEngine of the classic mode
import { MatchService } from 'src/match/Match.service'; // use to acces function for the MatchEntity in the gameEngine to store goal
Expand Down Expand Up @@ -476,6 +476,19 @@ export class GameUpdateCenterGateway implements OnGatewayInit, OnGatewayConnecti
}
}

@SubscribeMessage("matchHistory")
handleMatchHistory(@MessageBody() data: matchHistoryDto, @ConnectedSocket() client: Socket) {
this.tokenChecker(client)
.then((user) => {
if (user) {
this.matchservice.matchHistory(data.userId)
.then((matches) => {
client.emit("matchHistory", matches);
})
}
})
}

/**
* nicolas' function
* @param client
Expand Down Expand Up @@ -503,7 +516,7 @@ export class GameUpdateCenterGateway implements OnGatewayInit, OnGatewayConnecti
let id: string = object.sub;
return id;
}

/**
* nicolas' function
* @param client
Expand Down
17 changes: 17 additions & 0 deletions back/nest_project/src/match/Match.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,21 @@ export class MatchService {
return this.MatchRepository.save(newMatch);
}

async matchHistory(userId: string): Promise<{matchId: string, winnerId: string, winnerLogin: string, scoreWinner: number, loserId: string, loserLogin: string, scoreLoser: number}[]> {
return this.MatchRepository
.createQueryBuilder("match")
.innerJoinAndSelect("match.winner", "winner")
.innerJoinAndSelect("match.loser", "loser")
.where("winner.id = :winnerId", {winnerId: userId})
.orWhere("loser.id = :loserId", {loserId: userId})
.select("match.id", "matchId")
.addSelect("winner.id", "winnerId")
.addSelect("winner.login", "winnerLogin")
.addSelect("match.score_winner", "scoreWinner")
.addSelect("loser.id", "loserId")
.addSelect("loser.login", "loserLogin")
.addSelect("match.score_loser", "scoreLoser")
.getRawMany();
}

}
4 changes: 4 additions & 0 deletions bugList.maroufladeDeValerieDamidot
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@

---Pour Clemence---

- a la creation d'un utilisateur, la mise a jour dans le tableau de la serach bar ne fonctionne plus

---Pour BouleMan---

- des matchs sont lancees en trop !

---Pour Diane---

- image provenant de avataaars ne s'affiche plus dans la page profil depuis le merge de Diane
Expand Down
38 changes: 19 additions & 19 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,25 +59,25 @@ services:
# - db
# restart: always
########################################### VOLUMES #########################################
# volumes:
# db:
# driver: local
# driver_opts:
# type: none
# o: bind
# device: ./postgres
# back:
# driver: local
# driver_opts:
# type: none
# o: bind
# device: ./back
# front:
# driver: local
# driver_opts:
# type: none
# o: bind
# device: ./front
volumes:
db:
driver: local
driver_opts:
type: none
o: bind
device: ./postgres
back:
driver: local
driver_opts:
type: none
o: bind
device: ./back
front:
driver: local
driver_opts:
type: none
o: bind
device: ./front
# pgadmin:
# driver: local
# driver_opts:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export class MessageList extends React.Component<{history: IMessage[], handleHis
checkBlock(senderName: string) {
let block: boolean = false;
for (let elt of this.state.usersBlocked) {

if (elt.name == senderName) {
block = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export default function BlockList() {
}, []);

return (
<div id="block">
<div>
{blocked.length > 0 && <div id="block">
{blocked.length > 0 && <div id="titleBlock">
<h3>
User{blocked.length > 1 && "s"} I blocked
Expand All @@ -47,7 +48,7 @@ export default function BlockList() {
{develop && <ul id="blockList">
{blocked.map((elt, id) => (
<li id="blockElement" key={id}>
<span>{elt.name}</span>
<span className="name">{elt.name}</span>
<NavLink id="checkProfileButton" to={`/profile/${elt.id}`}>
<FontAwesomeIcon className="iconAction" icon={faAddressCard} />
</NavLink>
Expand All @@ -57,6 +58,7 @@ export default function BlockList() {
</li>
))}
</ul>}
</div>}
</div>
)
}
15 changes: 9 additions & 6 deletions front/react_project/src/components/ProfileModule/FriendList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class FriendList extends React.Component<{socket: Socket}, {
toPush.key.concat('0');
friendsArray.push(toPush);
}
friendsArray.sort((a, b) => {return a.friendName.localeCompare(b.friendName)})
this.setState({
friends: friendsArray,
fetchFriendsDone: true});
Expand Down Expand Up @@ -155,19 +156,20 @@ class FriendList extends React.Component<{socket: Socket}, {

render() {
return (
<div id="friend">
{this.state.friends.length > 0 && <div id="titleFriend">
<div>
{this.state.friends.length > 0 && <div id="friend">
<div id="titleFriend">
<h3>My friend{this.state.friends.length > 1 && "s"}</h3>
<button id="developButton" onClick={this.invertDevelop}>
{this.state.develop ? <FontAwesomeIcon icon={faArrowUp} />
: <FontAwesomeIcon icon={faArrowDown} />}
</button>
</div>}
</div>
{this.state.develop && <ul id="friendList">
{this.state.friends.map((elt) => (
<li id="friendElement" key={elt.key}>
<span id="friendInfo">
<div id="friendName">{elt.friendName}</div>
<div className="name">{elt.friendName}</div>
<div className={elt.isConnected ? "circle online" : "circle offline"}></div>
</span>
<span id="friendOptions">
Expand All @@ -179,16 +181,17 @@ class FriendList extends React.Component<{socket: Socket}, {
<FontAwesomeIcon className="iconAction" icon={faCommentDots} />
</NavLink>
</button>
<button value={elt.friendId} data-hover-text="invite to play" id="inviteToGame" onClick={this.inviteToGameHandler}>
{elt.isConnected && <button value={elt.friendId} data-hover-text="invite to play" id="inviteToGame" onClick={this.inviteToGameHandler}>
<FontAwesomeIcon className="iconAction" icon={faPingPongPaddleBall} />
</button>
</button>}
<button value={elt.friendshipId} data-hover-text="unfriend" id="unfriendButton" onClick={this.unfriendHandler}>
<FontAwesomeIcon className="iconAction" icon={faTrashCan} />
</button>
</span>
</li>
))}
</ul>}
</div>}
</div>
)
}
Expand Down
71 changes: 71 additions & 0 deletions front/react_project/src/components/ProfileModule/MatchHistory.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { useContext, useEffect, useState } from "react";
import { SocketContext } from "../context";
import { JwtPayload } from "jsonwebtoken";
import { accountService } from "../../services/account.service";

export default function MatchHistory(props: {userId: string}) {
const {socketGame} = useContext(SocketContext);
const [history, setHistory] = useState<{
matchId: string,
winnerId: string,
winnerLogin: string,
scoreWinner: number,
loserId: string,
loserLogin: string,
scoreLoser: number}[]>([]);
const [matchWon, setMatchWon] = useState<number>(0);
const [matchLost, setMatchLost] = useState<number>(0);


useEffect(() => {
socketGame.emit("matchHistory", {userId: props.userId});
}, [props.userId]);

useEffect(() => {
socketGame.on("matchHistory", (data: {
matchId: string,
winnerId: string,
winnerLogin: string,
scoreWinner: number,
loserId: string,
loserLogin: string,
scoreLoser: number}[] ) => {
let win = 0;
let loose = 0;
data.forEach((elt) => {
if (elt.winnerId == props.userId)
++win;
else
++loose;
});
console.log("win: ", win, ", loose: ", loose);
setMatchWon(win);
setMatchLost(loose);
setHistory(data);
})
}, [])

return (
<div id="score">
<div id="stats">
<h2>Statistics</h2>
<h3>total win = {matchWon}</h3>
<h3>total lost = {matchLost}</h3>
<h3>ratio = {matchLost == 0 ? (matchWon == 0 ? "NaN" : "full perfect") : matchWon / matchLost}</h3>
</div>
<div id="history">
<h2>Match history</h2>
<ul id="matchList">
{history.map((elt) => (
<li id="historyElement" key={elt.matchId}>
<span id="winnerName" className="name">{elt.winnerLogin}</span>
<span id="winnerScore">{elt.scoreWinner}</span>
<span id="loserName" className="name">{elt.loserLogin}</span>
<span id="loserScore">{elt.scoreLoser}</span>
</li>
))}
</ul>
</div>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ export default function PendingList() {
}, [pendings]);

return (
<div id="pending">
{pendings.length > 0 &&
<div>
{pendings.length > 0 && <div id="pending">
<div id="titlePending">
<h3>
My pending request{pendings.length > 1 && "s"}
Expand All @@ -68,11 +68,11 @@ export default function PendingList() {
{develop ? <FontAwesomeIcon icon={faArrowUp} />
: <FontAwesomeIcon icon={faArrowDown} />}
</button>
</div>}
</div>
{develop && <ul id="pendingList">
{pendings.map((elt) => (
<li id="pendingElement" key={elt.friendId}>
<span>{elt.friendName}</span>
<span className="name">{elt.friendName}</span>
<NavLink id="checkProfileButton" to={`/profile/${elt.friendId}`}>
<FontAwesomeIcon className="iconAction" icon={faAddressCard} />
</NavLink>
Expand All @@ -82,6 +82,7 @@ export default function PendingList() {
</li>
))}
</ul>}
</div>}
</div>
)
}
24 changes: 7 additions & 17 deletions front/react_project/src/components/ProfileModule/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,20 @@ import FriendList from "./FriendList";
import PendingList from "./PendingList";
import RequestsList from "./RequestList";
import BlockList from "./BlockList";
import MatchHistory from "./MatchHistory";

export default function Profile() {
const {socket} = useContext(SocketContext);
const {socketGame} = useContext(SocketContext);
const navigate = useNavigate();
const [user, setUser] = useState<User>();
const currentUser = useParams().login;

useEffect(() => {
console.log("loop")
if (currentUser !== undefined){
userService.getUser(currentUser)
.then(response => {
console.log("Profile 26: user ", response.data);
if (response.data === "") {
navigate('/profile');
}
Expand All @@ -44,6 +46,7 @@ export default function Profile() {
console.log(error);
});
}
console.log(user?.login);

return () => {
if (socket) {
Expand All @@ -55,13 +58,10 @@ export default function Profile() {
socket.off("userIsConnected");
socket.off("userConnected");
socket.off("userDisconnected");
socketGame.off("matchHistory");
}
}
}, [currentUser])

useEffect(() => {
// console.log('user', user);
}, [user])
}, [currentUser, navigate])

return (

Expand All @@ -86,17 +86,7 @@ export default function Profile() {
</div>
): null}
</aside>
<div id="score">
<div id="stats">
<h2>Statistics</h2>

</div>
<div id="history">
<h2>Match History</h2>

</div>
</div>

{socketGame && user != undefined && <MatchHistory userId={user.id!} />}
</div>
)
}

0 comments on commit b8e3c7b

Please sign in to comment.