From 24c52945852b23cd7674a41b29c699f1c7e89731 Mon Sep 17 00:00:00 2001 From: ismail Date: Thu, 16 Nov 2023 03:37:07 +0100 Subject: [PATCH 1/3] Fixing bugs --- backend/code/accountPickerCli.ts | 2 +- backend/code/prisma/Dockerfile | 13 + backend/code/prisma/dbml/schema.dbml | 8 +- .../migration.sql | 14 + backend/code/prisma/schema.prisma | 5 +- backend/code/src/app.controller.ts | 10 +- backend/code/src/gateways/gateways.gateway.ts | 30 +- backend/code/src/main.ts | 6 +- backend/code/src/messages/messages.service.ts | 44 +- .../src/profile/dto/update-profile.dto.ts | 8 +- backend/code/src/rooms/dto/create-room.dto.ts | 1 + backend/code/src/rooms/rooms.service.ts | 73 +- backend/code/src/users/dto/update-user.dto.ts | 2 + docker-compose.yaml | 16 + frontend/code/README.md | 2 +- frontend/code/package.json | 5 +- frontend/code/src/Api/base.tsx | 20 - .../Chat/Components/Conversation.tsx | 345 +++---- .../Components/Chat/Components/RecentChat.tsx | 186 ++-- .../Chat/Components/RoomChatHelpers.tsx | 843 +++++++++--------- .../Chat/Components/UserToUserChat.tsx | 5 - .../Chat/Controllers/LayoutControllers.tsx | 33 +- .../Components/Chat/Services/ChatServices.ts | 60 +- .../Chat/Services/FriendsServices.ts | 87 +- .../Chat/Services/MessagesServices.ts | 23 +- .../Chat/Services/SocketsServices.ts | 3 +- frontend/code/src/Components/Chat/index.tsx | 28 +- .../Components/FirstLogin/UploadAvatar.tsx | 15 +- frontend/code/src/Components/Game/index.tsx | 306 ++++--- .../src/Components/Layout/Assets/Alert.tsx | 16 +- .../Layout/Assets/Invitationacceptance.tsx | 12 +- .../Layout/Assets/Invitationmodale.tsx | 6 +- .../src/Components/Layout/Assets/Modal.tsx | 22 +- .../src/Components/Layout/Assets/Search.tsx | 94 +- frontend/code/src/Components/Layout/index.tsx | 125 +-- frontend/code/src/Components/Login/index.tsx | 2 - .../src/Components/Play/assets/queuemodal.tsx | 2 +- frontend/code/src/Components/Play/index.tsx | 8 +- .../src/Components/Profile/assets/Table.tsx | 2 +- .../code/src/Components/Profile/index.tsx | 45 +- .../src/Components/Settings/assets/Inputs.tsx | 13 +- .../code/src/Components/Settings/index.tsx | 8 +- .../code/src/Components/Validate2Fa/index.tsx | 4 +- frontend/code/src/Stores/stores.ts | 18 +- frontend/code/src/index.tsx | 3 - nginx/default.conf | 4 +- 46 files changed, 1284 insertions(+), 1293 deletions(-) create mode 100644 backend/code/prisma/Dockerfile create mode 100644 backend/code/prisma/migrations/20231116010258_fix_block_relation/migration.sql diff --git a/backend/code/accountPickerCli.ts b/backend/code/accountPickerCli.ts index ad90f7f..9cb9e72 100644 --- a/backend/code/accountPickerCli.ts +++ b/backend/code/accountPickerCli.ts @@ -66,7 +66,7 @@ var requestOptions = { redirect: 'follow' }; -fetch("http://localhost:3001/auth/login", requestOptions) +fetch("http://test.reversablecode.com:3001/auth/login", requestOptions) .then(response => response.text()) .then(result => console.log(result)) .catch(error => console.log('error', error));`; diff --git a/backend/code/prisma/Dockerfile b/backend/code/prisma/Dockerfile new file mode 100644 index 0000000..f7d7150 --- /dev/null +++ b/backend/code/prisma/Dockerfile @@ -0,0 +1,13 @@ +FROM node:18 + +# Create app directory +WORKDIR /app + +# Install prisma for the migration +RUN npm install -g prisma --unsafe-perm + +# Copy schema and migration folder +ADD ./ ./prisma/ + +# Run migration +CMD ["prisma", "migrate", "deploy"] \ No newline at end of file diff --git a/backend/code/prisma/dbml/schema.dbml b/backend/code/prisma/dbml/schema.dbml index 6b7f374..0ffaa10 100644 --- a/backend/code/prisma/dbml/schema.dbml +++ b/backend/code/prisma/dbml/schema.dbml @@ -53,10 +53,14 @@ Table blocked_friends { createdAt DateTime [default: `now()`, not null] id String [pk] Blcoked_by users [not null] - blocked_by_id String [unique, not null] + blocked_by_id String [not null] Blocked users [not null] - blocked_id String [unique, not null] + blocked_id String [not null] dmRoomId String + + indexes { + (blocked_by_id, blocked_id) [unique] + } } Table matches { diff --git a/backend/code/prisma/migrations/20231116010258_fix_block_relation/migration.sql b/backend/code/prisma/migrations/20231116010258_fix_block_relation/migration.sql new file mode 100644 index 0000000..48f9673 --- /dev/null +++ b/backend/code/prisma/migrations/20231116010258_fix_block_relation/migration.sql @@ -0,0 +1,14 @@ +/* + Warnings: + + - A unique constraint covering the columns `[blocked_by_id,blocked_id]` on the table `blocked_friends` will be added. If there are existing duplicate values, this will fail. + +*/ +-- DropIndex +DROP INDEX "blocked_friends_blocked_by_id_key"; + +-- DropIndex +DROP INDEX "blocked_friends_blocked_id_key"; + +-- CreateIndex +CREATE UNIQUE INDEX "blocked_friends_blocked_by_id_blocked_id_key" ON "blocked_friends"("blocked_by_id", "blocked_id"); diff --git a/backend/code/prisma/schema.prisma b/backend/code/prisma/schema.prisma index 9290dfb..f3e605a 100644 --- a/backend/code/prisma/schema.prisma +++ b/backend/code/prisma/schema.prisma @@ -71,11 +71,12 @@ model BlockedUsers { id String @id Blcoked_by User @relation("blocked_by", fields: [blocked_by_id], references: [userId], onDelete: Cascade) - blocked_by_id String @unique + blocked_by_id String Blocked User @relation("blocked", fields: [blocked_id], references: [userId], onDelete: Cascade) - blocked_id String @unique + blocked_id String dmRoomId String? + @@unique([blocked_by_id, blocked_id], name: "unique_block") @@map("blocked_friends") } diff --git a/backend/code/src/app.controller.ts b/backend/code/src/app.controller.ts index d27d2e6..270ab05 100644 --- a/backend/code/src/app.controller.ts +++ b/backend/code/src/app.controller.ts @@ -106,7 +106,7 @@ export class AppController { - Socket.io Example - - - - -

Socket.io Example

- -
- - - - - - -
- - - - - -
- - - - - - -
- - - - - -
- - -
- - - -
-
- - -`; - } } diff --git a/backend/code/src/auth/stratgies/ft.strategy.ts b/backend/code/src/auth/stratgies/ft.strategy.ts index 2aeb8ca..a128046 100644 --- a/backend/code/src/auth/stratgies/ft.strategy.ts +++ b/backend/code/src/auth/stratgies/ft.strategy.ts @@ -48,7 +48,7 @@ export class FtStrategy extends PassportStrategy(Strategy, '42') { user.userId, tokens.refresh_token, ); - console.log(tokens); + res.cookie('X-Access-Token', tokens.access_token, { httpOnly: true }); res.cookie('X-Refresh-Token', tokens.refresh_token, { httpOnly: true, diff --git a/backend/code/src/friends/friends.service.ts b/backend/code/src/friends/friends.service.ts index 3b7b38e..2868801 100644 --- a/backend/code/src/friends/friends.service.ts +++ b/backend/code/src/friends/friends.service.ts @@ -38,7 +38,6 @@ export class FriendsService { }, update: {}, }); - // this.evenEmitter.emit('addFriendNotif', notifData); TODO: emit an event with the correct data this.evenEmitter.emit('sendNotification', { receiverId: friendId, actorId: userId, diff --git a/backend/code/src/game/game.controller.ts b/backend/code/src/game/game.controller.ts index 657ebf8..1935229 100644 --- a/backend/code/src/game/game.controller.ts +++ b/backend/code/src/game/game.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get, Post, Query, UseGuards, Param } from '@nestjs/common'; +import { Controller, Get, Query, UseGuards, Param } from '@nestjs/common'; import { GameService } from './game.service'; import { AtGuard } from 'src/auth/guards/at.guard'; import { GetCurrentUser } from 'src/auth/decorator/get_current_user.decorator'; @@ -10,11 +10,6 @@ import { ApiTags } from '@nestjs/swagger'; export class GameController { constructor(private readonly gameService: GameService) {} - @Post('start') - startGame() { - // return this.gameService.startGame(); - } - @Get('history') @UseGuards(AtGuard) getHistory( diff --git a/backend/code/src/game/game.service.ts b/backend/code/src/game/game.service.ts index 9b50781..62e2346 100644 --- a/backend/code/src/game/game.service.ts +++ b/backend/code/src/game/game.service.ts @@ -38,7 +38,6 @@ export class GameService { this.classicwaitingPlayers.push({ socket: client, userData: userData }); else if (gameMode === 'extra') this.extraWaitingPlayers.push({ socket: client, userData: userData }); - console.log('client subscribed to the queue'); } else if (data.mode === 'unregister') { const client = data.client; const gameMode = data.gameMode; @@ -57,25 +56,13 @@ export class GameService { //NOTE: add game modes here private launchGame() { setInterval(() => { - // console.log('waitingPlayers', this.classicwaitingPlayers.length); - console.log('waitingPlayers classic', this.classicwaitingPlayers.length); - console.log('waitingPlayers extra', this.extraWaitingPlayers.length); - if (this.classicwaitingPlayers.length >= 2) { - console.log('Game launched!'); const two_players = this.classicwaitingPlayers.splice(0, 2); this.eventEmitter.emit('game.launched', two_players, 'classic'); - console.log(two_players); - // const user = await this.getUser(two_players[0].data.user.sub) - // console.log(user) } if (this.extraWaitingPlayers.length >= 2) { - console.log('Game launched!'); const two_players = this.extraWaitingPlayers.splice(0, 2); this.eventEmitter.emit('game.launched', two_players, 'extra'); - console.log(two_players); - // const user = await this.getUser(two_players[0].data.user.sub) - // console.log(user) } }, 5027); } diff --git a/backend/code/src/game/game.ts b/backend/code/src/game/game.ts index 5d64a2c..7ec39e8 100644 --- a/backend/code/src/game/game.ts +++ b/backend/code/src/game/game.ts @@ -43,8 +43,6 @@ export class Game { const scale2 = player2.h / this.h; const newPos = this.p1PaddleY * scale2; - // let scale_y = player2.h / this.h; - // let center = this.paddleHeight * scale_y; if (p2PaddleY - player2.h / 6 / 6 < 0) { p2PaddleY = 0; @@ -72,9 +70,6 @@ export class Game { const scale2 = player1.h / this.h; const newPos = this.p2PaddleY * scale2; - // let scale_y = player1.h / this.h; - - // let center = this.paddleHeight * scale_y; if (p1PaddleY - player1.h / 6 / 6 < 0) { p1PaddleY = 0; @@ -114,13 +109,7 @@ export class Game { private async loop() { if (this.closeGame) return; - console.log('loop'); - // if ( - // this.x + this.dx + this.ballSize / 2 >= this.w || - // this.x + this.dx - this.ballSize / 2 <= 0 - // ) - // this.dx *= -1; if ( this.y + this.dy + this.ballSize / 2 >= this.h || this.y + this.dy - this.ballSize / 2 <= 0 @@ -151,7 +140,6 @@ export class Game { this.y > this.p2PaddleY + this.paddleHeight) && this.x + this.ballSize / 2 >= this.w ) { - console.log(`${this.p1PaddleY} ${this.x} ${this.y} ${this.ballSize}`); this.p1Score += 1; this.init(); this.checkForWinner(); @@ -162,33 +150,15 @@ export class Game { this.y > this.p1PaddleY + this.paddleHeight) && this.x - this.ballSize / 2 <= 0 ) { - console.log(`${this.p1PaddleY} ${this.x} ${this.y} ${this.ballSize}`); this.p2Score += 1; this.init(); this.checkForWinner(); await new Promise((resolve) => setTimeout(resolve, 1000)); } - console.log(this.x); - console.log(this.y); - - // const forwardx = this.x + this.dx; - // const forwardy = this.y + this.dy - // if (forwardx > this.) { - // } this.x += this.dx; this.y += this.dy; - // if ( - // parseFloat((this.p1Res.w / this.p1Res.h).toFixed(1)) !== 1.8 && - // parseFloat((this.p2Res.w / this.p2Res.h).toFixed(1)) !== 1.9 - // ) { - // this.p1socket.emit('screen Error'); - - // this.emitGameEnd('p1Leave'); - // this.p1socket.emit('lose', 'trying cheat'); - // this.p2socket.emit('win', 'you win other player try to cheat'); - // } else { this.p1socket.emit( 'ball', this.screenAdapter(this.p1Res, this.x, this.y, this.ballSize), @@ -203,18 +173,7 @@ export class Game { true, ), ); - // } - - // if ( - // parseFloat((this.p2Res.w / this.p2Res.h).toFixed(1)) !== 1.8 && - // parseFloat((this.p2Res.w / this.p2Res.h).toFixed(1)) !== 1.9 - // ) { - // this.p1socket.emit('screen Error'); - - // this.emitGameEnd('p2Leave'); - // this.p1socket.emit('win', 'you win other player try to cheat'); - // this.p2socket.emit('lose', 'trying cheat'); - // } else { + this.p2socket.emit( 'ball', this.screenAdapter(this.p2Res, this.x, this.y, this.ballSize), @@ -229,7 +188,6 @@ export class Game { true, ), ); - // } await this.sleep(this.frames); @@ -247,10 +205,8 @@ export class Game { } } async start(ngameid: string) { - console.log('game started', ngameid); this.gameid = ngameid; await this.sleepCounter(); - // await this.setplayerScokets(this.p1socket, this.p2socket ,) this.loop(); } @@ -264,10 +220,7 @@ export class Game { this.p2socket = p2socket; this.p1Data = p1Data; this.p2Data = p2Data; - console.log(p1Data); - console.log(p2Data); this.server.emit('players', [p1Data, p2Data]); - console.log('newfunc'); if (this.mode === 'extra') { let l = 1; @@ -323,26 +276,10 @@ export class Game { this.p2socket.on('screen', (data) => { this.p2Res = data; }); - this.p1socket.on('disconnect', () => { - this.emitGameEnd('p1Leave'); - this.p2socket.emit('win', 'you win other player leave the game'); - this.p1socket.emit('lose', 'you win other player leave the game'); - }); - this.p2socket.on('disconnect', () => { - this.emitGameEnd('p2Leave'); - this.p1socket.emit('win', 'you win other player leave the game'); - this.p2socket.emit('lose', 'you lost other player leave the game'); - }); - this.p1socket.on('leave', () => { - this.emitGameEnd('p1Leave'); - this.p2socket.emit('win', 'you win other player leave the game'); - this.p1socket.emit('lose', 'you win other player leave the game'); - }); - this.p2socket.on('leave', () => { - this.emitGameEnd('p2Leave'); - this.p1socket.emit('win', 'you win other player leave the game'); - this.p2socket.emit('lose', 'you lost other player leave the game'); - }); + this.p1socket.once('disconnect', this.handleP1Disconnect); + this.p2socket.once('disconnect', this.handleP2Disconnect); + this.p1socket.once('leave', this.handleP1Disconnect); + this.p2socket.once('leave', this.handleP2Disconnect); } private checkForWinner() { if (this.p1Score >= 5) { @@ -357,19 +294,32 @@ export class Game { } } + private handleP1Disconnect = () => { + this.p2socket.emit('win', 'you win other player leave the game'); + this.p1socket.emit('lose', 'you win other player leave the game'); + this.emitGameEnd('p1Leave'); + }; + + private handleP2Disconnect = () => { + this.p1socket.emit('win', 'you win other player leave the game'); + this.p2socket.emit('lose', 'you lost other player leave the game'); + this.emitGameEnd('p2Leave'); + }; + private removeListeners(socket: Socket) { - socket.removeAllListeners('disconnect'); - socket.removeAllListeners('leave'); socket.removeAllListeners('screen'); socket.removeAllListeners('mouse'); socket.removeAllListeners('up'); socket.removeAllListeners('down'); } private emitGameEnd(message: string) { - console.log`asdaqwe Game end`; this.closeGame = true; this.removeListeners(this.p1socket); + this.p1socket.off('leave', this.handleP1Disconnect); + this.p1socket.off('disconnect', this.handleP1Disconnect); this.removeListeners(this.p2socket); + this.p2socket.off('leave', this.handleP2Disconnect); + this.p2socket.off('disconnect', this.handleP2Disconnect); if (message === 'p1Leave') { this.eventEmitter.emit('game.end', { diff --git a/backend/code/src/gateways/gateways.gateway.ts b/backend/code/src/gateways/gateways.gateway.ts index b9e6765..dbe7015 100644 --- a/backend/code/src/gateways/gateways.gateway.ts +++ b/backend/code/src/gateways/gateways.gateway.ts @@ -8,7 +8,7 @@ import { } from '@nestjs/websockets'; import { Server, Socket } from 'socket.io'; import { MessageFormatDto } from 'src/messages/dto/message-format.dto'; -import { } from '@nestjs/platform-socket.io'; +import {} from '@nestjs/platform-socket.io'; import { EventEmitter2, OnEvent } from '@nestjs/event-emitter'; import { PrismaService } from 'src/prisma/prisma.service'; import { Game } from 'src/game/game'; @@ -35,7 +35,7 @@ export class Gateways implements OnGatewayConnection, OnGatewayDisconnect { private prisma: PrismaService, private readonly eventEmitter: EventEmitter2, private readonly usersService: UsersService, - ) { } + ) {} @WebSocketServer() private server: Server; private games_map = new Map(); @@ -75,10 +75,23 @@ export class Gateways implements OnGatewayConnection, OnGatewayDisconnect { const userId = client.data.user.sub; this.server.emit('friendOffline', userId); + this.eventEmitter.emit('game.start', { + client, + gameMode: 'cassic', + mode: 'unregister', + }); + this.eventEmitter.emit('game.start', { + client, + gameMode: 'extra', + mode: 'unregister', + }); } @OnEvent('sendMessages') - async sendMessage(message: MessageFormatDto, blockedRoomMembersIds?: string[]) { + async sendMessage( + message: MessageFormatDto, + blockedRoomMembersIds?: string[], + ) { const chanellname: string = `Room:${message.roomId}`; if (!blockedRoomMembersIds) { this.server.to(chanellname).emit('message', message); @@ -127,7 +140,10 @@ export class Gateways implements OnGatewayConnection, OnGatewayDisconnect { } @OnEvent('sendNotification') - async sendNotification(notif: Partial, blockedRoomMembersIds?: string[]) { + async sendNotification( + notif: Partial, + blockedRoomMembersIds?: string[], + ) { // create the notification on the database switch (notif.type) { case $Enums.NotifType.acceptFriend: @@ -211,7 +227,6 @@ export class Gateways implements OnGatewayConnection, OnGatewayDisconnect { @SubscribeMessage('status') async handleStatusEvent(@MessageBody() data: any) { - console.log('status event', data); const userId = data.userId; const status = this.server.sockets.adapter.rooms.get(`User:${userId}`)?.size ? 'online' @@ -248,10 +263,6 @@ export class Gateways implements OnGatewayConnection, OnGatewayDisconnect { }); } - // @SubscribeMessage('getPlayers') - // getPlayers() { - // this.server.emit("players",[this.p1Data ,this.p2Data]) - // } private async checkIfCanInvite(userId: string) { const opententSockets = await this.server .in(`User:${userId}`) @@ -309,10 +320,6 @@ export class Gateways implements OnGatewayConnection, OnGatewayDisconnect { const game_invite = Array.from(this.game_invites).find( (invite) => invite.gameId === data.gameId, ); - //TODO: check if user is already in queue - // check if already has an active invite from anyone - // check if he is already on game || save if user is in game by saving it in the data of socket - // check if user is offline if (!game_invite) { client.emit('game.declined', { gameId: data.gameId, @@ -358,13 +365,11 @@ export class Gateways implements OnGatewayConnection, OnGatewayDisconnect { this.game_invites.delete(game_invite); if (game_invite.inviter === client.data.user.sub) { - console.log('declined by inviter'); this.server.to(`User:${game_invite.opponentId}`).emit('game.declined', { decliner: client.data.user.sub, gameId: data.gameId, }); } else { - console.log('decliner is the opponent'); this.server.to(`User:${game_invite.inviter}`).emit('game.declined', { decliner: client.data.user.sub, gameId: data.gameId, @@ -375,7 +380,7 @@ export class Gateways implements OnGatewayConnection, OnGatewayDisconnect { @OnEvent('game.launched') async handleGameLaunchedEvent(clients: any, mode: string) { const game_channel = crypto.randomBytes(16).toString('hex'); - // console.log(game_channel); + clients.forEach((client: any) => { client.socket.join(game_channel); client.socket.data.user.inGame = true; @@ -397,11 +402,9 @@ export class Gateways implements OnGatewayConnection, OnGatewayDisconnect { @OnEvent('game.end') async handleGameEndEvent(data: any) { this.games_map.delete(data.gameid); - console.log('game ended'); - console.log(data); + const sockets = await this.server.in(data.gameid).fetchSockets(); this.server.to(data.gameid).emit('game.end', data); - console.log(data); for await (const socket of sockets) { socket.data.user.inGame = false; diff --git a/backend/code/src/messages/dto/message-format.dto.ts b/backend/code/src/messages/dto/message-format.dto.ts index da9266a..0acee39 100644 --- a/backend/code/src/messages/dto/message-format.dto.ts +++ b/backend/code/src/messages/dto/message-format.dto.ts @@ -9,7 +9,7 @@ export class MessageFormatDto { author: Partial; room?: { type: $Enums.RoomType }; }, - clientMessageId?: string + clientMessageId?: string, ) { this.id = messageData.id; this.content = messageData.content; diff --git a/backend/code/src/messages/messages.service.ts b/backend/code/src/messages/messages.service.ts index aef1f5d..806e2f4 100644 --- a/backend/code/src/messages/messages.service.ts +++ b/backend/code/src/messages/messages.service.ts @@ -9,11 +9,13 @@ export class MessagesService { constructor( private prisma: PrismaService, private eventEmitter: EventEmitter2, - ) { } + ) {} async sendMessages(userId: string, channelId: string, messageDto: any) { if (messageDto.content.length > 1000) { throw new HttpException('Message is too long', HttpStatus.BAD_REQUEST); + } else if (messageDto.content === '[REDACTED]') { + throw new HttpException('Message is not allowed', HttpStatus.BAD_REQUEST); } const room = await this.prisma.room.findUnique({ @@ -64,7 +66,12 @@ export class MessagesService { if (roomMember.is_mueted) { const now = new Date(); if (now < roomMember.mute_expires) { - throw new HttpException(`You are muted for ${Math.round((roomMember.mute_expires.valueOf() - now.valueOf()) / 1000)} seconds`, HttpStatus.FORBIDDEN); + throw new HttpException( + `You are muted for ${Math.round( + (roomMember.mute_expires.valueOf() - now.valueOf()) / 1000, + )} seconds`, + HttpStatus.FORBIDDEN, + ); } await this.prisma.roomMember.update({ where: { @@ -100,27 +107,43 @@ export class MessagesService { const roomMembersIds = await this.prisma.roomMember.findMany({ where: { roomId: channelId, NOT: { userId } }, - select: { userId: true } + select: { userId: true }, }); const blockedUsersIds = await this.prisma.blockedUsers.findMany({ where: { OR: [{ blocked_by_id: userId }, { blocked_id: userId }] }, - select: { blocked_by_id: true, blocked_id: true } + select: { blocked_by_id: true, blocked_id: true }, }); - const blockedRoomMembersIds = roomMembersIds.filter((member) => { - return blockedUsersIds.some((blocked) => { - return blocked.blocked_by_id === member.userId || blocked.blocked_id === member.userId; - }); - }).map((member) => member.userId); - - const responseMessage: MessageFormatDto = new MessageFormatDto(messageData, messageDto.clientMessageId); - this.eventEmitter.emit('sendNotification', { - actorId: userId, - type: $Enums.NotifType.message, - entityId: messageData.id, - entity_type: 'message', - }, blockedRoomMembersIds.length ? blockedRoomMembersIds : undefined); - this.eventEmitter.emit('sendMessages', responseMessage, blockedRoomMembersIds.length ? blockedRoomMembersIds : undefined); + const blockedRoomMembersIds = roomMembersIds + .filter((member) => { + return blockedUsersIds.some((blocked) => { + return ( + blocked.blocked_by_id === member.userId || + blocked.blocked_id === member.userId + ); + }); + }) + .map((member) => member.userId); + + const responseMessage: MessageFormatDto = new MessageFormatDto( + messageData, + messageDto.clientMessageId, + ); + this.eventEmitter.emit( + 'sendNotification', + { + actorId: userId, + type: $Enums.NotifType.message, + entityId: messageData.id, + entity_type: 'message', + }, + blockedRoomMembersIds.length ? blockedRoomMembersIds : undefined, + ); + this.eventEmitter.emit( + 'sendMessages', + responseMessage, + blockedRoomMembersIds.length ? blockedRoomMembersIds : undefined, + ); return responseMessage; } @@ -170,7 +193,7 @@ export class MessagesService { take: limit, }); - // get rppm type of room + // get room type of room const room = await this.prisma.room.findUnique({ where: { id: channelId, diff --git a/backend/code/src/profile/profile.service.ts b/backend/code/src/profile/profile.service.ts index d97f361..716332d 100644 --- a/backend/code/src/profile/profile.service.ts +++ b/backend/code/src/profile/profile.service.ts @@ -28,8 +28,8 @@ export class ProfileService { wonMatches === 0 ? null : wonMatches >= 100 - ? 2 - : Math.floor(Math.log10(wonMatches)); + ? 2 + : Math.floor(Math.log10(wonMatches)); return new ProfileDto({ ...user, achievement }, false); } @@ -58,8 +58,8 @@ export class ProfileService { wonMatches === 0 ? null : wonMatches >= 100 - ? 2 - : Math.floor(Math.log10(wonMatches)); + ? 2 + : Math.floor(Math.log10(wonMatches)); return new ProfileDto({ ...user, achievement }, true); } diff --git a/backend/code/src/rooms/dto/create-room.dto.ts b/backend/code/src/rooms/dto/create-room.dto.ts index 3c2cc71..13b94c5 100644 --- a/backend/code/src/rooms/dto/create-room.dto.ts +++ b/backend/code/src/rooms/dto/create-room.dto.ts @@ -10,7 +10,6 @@ import { } from 'class-validator'; export class CreateRoomDto { - // @IgnoreName('type', { message: 'room name is not required on type dm' }) @ApiProperty({ description: 'name of the room required if type is not dm' }) @IsString() @IsNotEmpty() diff --git a/backend/code/src/rooms/rooms.service.ts b/backend/code/src/rooms/rooms.service.ts index d48515e..bda0473 100644 --- a/backend/code/src/rooms/rooms.service.ts +++ b/backend/code/src/rooms/rooms.service.ts @@ -20,7 +20,7 @@ import { roomsData } from './types/room-types'; @Injectable() export class RoomsService { - constructor(private prisma: PrismaService) { } + constructor(private prisma: PrismaService) {} async createRoom(roomData: CreateRoomDto, roomOwnerId: string) { if (roomData.type == 'protected' && !roomData.password) { @@ -612,8 +612,14 @@ export class RoomsService { skip: offset, take: limit, where: { - ...(joined && { members: { some: { userId: userId } }, NOT: { type: 'dm' } }), - ...(!joined && { NOT: { members: { some: { userId } } }, OR: [{ type: 'public' }, { type: 'protected' }] }), + ...(joined && { + members: { some: { userId: userId } }, + NOT: { type: 'dm' }, + }), + ...(!joined && { + NOT: { members: { some: { userId } } }, + OR: [{ type: 'public' }, { type: 'protected' }], + }), }, select: { id: true, @@ -662,10 +668,10 @@ export class RoomsService { }); const blocked = last_message ? await this.prisma.blockedUsers.findFirst({ - where: { - id: [userId, last_message.authorId].sort().join('-'), - }, - }) + where: { + id: [userId, last_message.authorId].sort().join('-'), + }, + }) : null; const is_owner = room.ownerId === userId; diff --git a/backend/code/src/users/users.service.ts b/backend/code/src/users/users.service.ts index 9b389db..f1b71d5 100644 --- a/backend/code/src/users/users.service.ts +++ b/backend/code/src/users/users.service.ts @@ -154,14 +154,11 @@ export class UsersService { } if (dataDto.action === TwoFactorAction.ENABLE && !user.tfaEnabled) { - console.log(dataDto); // generate a top with the same secret - console.log(authenticator.generate(dataDto.secret)); const isValid = authenticator.verify({ token: dataDto.otp, secret: dataDto.secret, }); - console.log(authenticator.keyuri('test', 'test', dataDto.secret)); if (!isValid) { throw new HttpException('Invalid OTP', 400); diff --git a/backend/code/test/app.e2e-spec.ts b/backend/code/test/app.e2e-spec.ts index f4a316f..fc3acfe 100644 --- a/backend/code/test/app.e2e-spec.ts +++ b/backend/code/test/app.e2e-spec.ts @@ -23,20 +23,4 @@ describe('AppController (e2e)', () => { }); }); - - - - - - - - - - - - - - - - //kslsl diff --git a/frontend/code/src/Api/base.tsx b/frontend/code/src/Api/base.tsx index 772542a..5203412 100644 --- a/frontend/code/src/Api/base.tsx +++ b/frontend/code/src/Api/base.tsx @@ -11,8 +11,8 @@ const apiWithoutManager = axios.create({ }); const ConcurrencyManager = (axios: any, MAX_CONCURRENT = 10) => { - if (MAX_CONCURRENT < 1){ - //eslint-disable-next-line + if (MAX_CONCURRENT < 1) { + //eslint-disable-next-line throw "Concurrency Manager Error: minimun concurrent requests is 1"; } let instance = { @@ -38,7 +38,7 @@ const ConcurrencyManager = (axios: any, MAX_CONCURRENT = 10) => { }, // Use as interceptor. Queue outgoing requests requestHandler: (req: any) => { - return new Promise(resolve => { + return new Promise((resolve) => { instance.push({ request: req, resolver: resolve }); }); }, @@ -51,31 +51,34 @@ const ConcurrencyManager = (axios: any, MAX_CONCURRENT = 10) => { responseErrorHandler: async (error: any) => { if (error?.response?.status === 401) { try { - const refreshError = await apiWithoutManager.get("auth/refresh").then(() => null).catch((err: any) => err); - if (refreshError && window.location.pathname !== '/') { + const refreshError = await apiWithoutManager + .get("auth/refresh") + .then(() => null) + .catch((err: any) => err); + if (refreshError && window.location.pathname !== "/") { instance.queue = []; instance.running = []; - window.location.href = '/'; + window.location.href = "/"; return; } const res = await apiWithoutManager.request(error.config); return instance.responseHandler(res); - } catch (refreshError) { } + } catch (refreshError) {} } return Promise.reject(instance.responseHandler(error)); }, interceptors: { request: null, - response: null + response: null, }, detach: () => { axios.interceptors.request.eject(instance.interceptors.request); axios.interceptors.response.eject(instance.interceptors.response); - } + }, }; // queue concurrent requests instance.interceptors.request = axios.interceptors.request.use( - instance.requestHandler + instance.requestHandler, ); instance.interceptors.response = axios.interceptors.response.use( instance.responseHandler, diff --git a/frontend/code/src/Components/Chat/Components/Conversation.tsx b/frontend/code/src/Components/Chat/Components/Conversation.tsx index 6ae2f9d..84c22cd 100644 --- a/frontend/code/src/Components/Chat/Components/Conversation.tsx +++ b/frontend/code/src/Components/Chat/Components/Conversation.tsx @@ -50,7 +50,7 @@ export const CurrentUserMessage = forwardRef((props, ref) => { ref={ref} className={classNames( "chat chat-end p-2 pl-5", - props.isPending && "opacity-50" + props.isPending && "opacity-50", )} >
@@ -61,7 +61,7 @@ export const CurrentUserMessage = forwardRef((props, ref) => {
{props.message} @@ -69,14 +69,14 @@ export const CurrentUserMessage = forwardRef((props, ref) => {
{props.isPending ? "Sending..." : props.isFailed - ? "Failed" - : "Delivered"} + ? "Failed" + : "Delivered"}
) : ( @@ -181,8 +181,8 @@ export const ConversationHeader: React.FC = ({ {selectedChatType === ChatType.Chat ? currentUser?.name : currentRoom?.isOwner - ? currentRoom.name + " ♚" - : currentRoom?.name} + ? currentRoom.name + " ♚" + : currentRoom?.name}

{selectedChatType === ChatType.Chat ? (

= ({ } user.setGameWaitingId(data.gameId); inviteWaitingModalRef.current?.showModal(); - } + }, ); }} > @@ -315,7 +315,6 @@ export const ConversationHeader: React.FC = ({ : "hide Room Info"} - {/* {currentRoom?.isOwner === false && ( */}

  • { @@ -324,7 +323,6 @@ export const ConversationHeader: React.FC = ({ ChatState.setIsLoading(false); if (res?.status === 200 || res?.status === 201) { toast.success("Room Left Successfully"); - // ChatState.changeChatType(ChatType.Chat); ChatState.deleteRoom(currentRoom?.id as string); } }); @@ -420,7 +418,6 @@ export const Conversation: React.FC = ({ friendId: chatState.currentDmUser.secondUserId, }); - // const handle socketStore.socket?.on("roomDeparture", handleLeave); socketStore.socket?.on("message", handleMessage); @@ -456,7 +453,7 @@ export const Conversation: React.FC = ({ senderId: message.authorId, message: message.content, time: message.time, - }) + }), ); chatState.fillCurrentMessages([...currentMessages, ...messages]); } @@ -554,10 +551,10 @@ const ConversationInput = (props: ConversationInputProps) => { chatState.setMessageAsFailed(res?.data.id); // Remove failed message chatState.removeMessageFromCurrentMessages( - (e) => e.clientMessageId !== clientMessageId + (e) => e.clientMessageId !== clientMessageId, ); } - } + }, ); }; diff --git a/frontend/code/src/Components/Chat/Components/RecentChat.tsx b/frontend/code/src/Components/Chat/Components/RecentChat.tsx index 8098ac7..705c3a0 100644 --- a/frontend/code/src/Components/Chat/Components/RecentChat.tsx +++ b/frontend/code/src/Components/Chat/Components/RecentChat.tsx @@ -75,7 +75,7 @@ export const RecentConversations = () => { }, bio: room.bio, }); - } + }, ); if (res.data.length > 0) { @@ -276,7 +276,7 @@ export const OnlineNowUsers = () => { // to inject it with the real images later avatar: friend.avatar, } as RoomMember); - } + }, ); setUsers(friends); @@ -381,10 +381,10 @@ export const OnlineNowUsers = () => { navigate(`/Dm/${res?.data.id}`); } else { toast.error( - "You Can't Send Message To this User For Now, try Again later" + "You Can't Send Message To this User For Now, try Again later", ); } - } + }, ); }} > diff --git a/frontend/code/src/Components/Chat/Components/RoomChatHelpers.tsx b/frontend/code/src/Components/Chat/Components/RoomChatHelpers.tsx index d99ccb2..448da3d 100644 --- a/frontend/code/src/Components/Chat/Components/RoomChatHelpers.tsx +++ b/frontend/code/src/Components/Chat/Components/RoomChatHelpers.tsx @@ -81,7 +81,7 @@ export const RoomChatPlaceHolder = () => { membersCount: room.countMembers, last_message: room.last_message, }); - } + }, ); setIsLoading(false); if (res.data.length > 0) { @@ -222,7 +222,7 @@ export const CreateNewRoomModal = () => { window.history.pushState( "", document.title, - window.location.pathname + window.location.search + window.location.pathname + window.location.search, ); modalState.setShowCreateChatRoomModal(false); }; @@ -245,7 +245,7 @@ export const CreateNewRoomModal = () => { createNewRoomCall( RoomName, RoomType[selectedOption], - selectedOption === RoomType.protected ? RoomPassword : undefined + selectedOption === RoomType.protected ? RoomPassword : undefined, ).then((res) => { if (res?.status !== 200 && res?.status !== 201) { toast.error("something went wrong, try again"); @@ -462,7 +462,7 @@ export const BlockedUsersModal = () => { window.history.pushState( "", document.title, - window.location.pathname + window.location.search + window.location.pathname + window.location.search, ); LayoutState.setShowBlockedListModal(false); }; @@ -496,7 +496,7 @@ export const BlockedUsersModal = () => { // to inject it with the real images later avatar: friend.avatar, } as RoomMember); - } + }, ); setUsers(friends); @@ -572,7 +572,7 @@ export const FriendStatusTile = (props: { user: RoomMember }) => { } else { setOnlineStatus("offline"); } - } + }, ); }, [user.id, socketStore?.socket]); return ( @@ -599,8 +599,8 @@ export const FriendStatusTile = (props: { user: RoomMember }) => { onlineStatus === "online" ? "text-green-500 border-green-500" : onlineStatus === "inGame" - ? "text-yellow-500 border-yellow-500" - : "text-red-500 border-red-500" + ? "text-yellow-500 border-yellow-500" + : "text-red-500 border-red-500", )} > {onlineStatus} @@ -621,7 +621,7 @@ export const FriendsListModal = () => { window.history.pushState( "", document.title, - window.location.pathname + window.location.search + window.location.pathname + window.location.search, ); LayoutState.setShowFriendsListModal(false); }; @@ -655,7 +655,7 @@ export const FriendsListModal = () => { // to inject it with the real images later avatar: friend.avatar, } as RoomMember); - } + }, ); setUsers(friends); @@ -726,7 +726,7 @@ export const AddUsersModal = () => { window.history.pushState( "", document.title, - window.location.pathname + window.location.search + window.location.pathname + window.location.search, ); LayoutState.setShowAddUsersModal(false); }; @@ -741,7 +741,7 @@ export const AddUsersModal = () => { await getRoomMembersCall( ChatState.selectedChatID as string, 0, - 20 + 20, ).then((res) => { setIsLoading(false); if (res?.status === 200 || res?.status === 201) { @@ -774,7 +774,7 @@ export const AddUsersModal = () => { // to inject it with the real images later avatar: friend.avatar, } as RoomMember); - } + }, ); setUsers(friends); @@ -807,7 +807,7 @@ export const AddUsersModal = () => {
    {currentFriends.filter( (friend) => - !currentRoomMembers.some((member) => member.id === friend.id) + !currentRoomMembers.some((member) => member.id === friend.id), ).length < 1 && ( )} @@ -815,8 +815,8 @@ export const AddUsersModal = () => { .filter( (friend) => !currentRoomMembers.some( - (member) => member.id === friend.id - ) + (member) => member.id === friend.id, + ), ) .map((user) => ( @@ -911,7 +911,7 @@ export const RoomSettingsModal = () => { window.history.pushState( "", document.title, - window.location.pathname + window.location.search + window.location.pathname + window.location.search, ); LayoutState.setShowSettingsModal(false); }; @@ -1068,7 +1068,7 @@ export const RoomSettingsModal = () => { takeActionCall( selectedChatID as string, user.id, - user.isBaned ? "unban" : "ban" + user.isBaned ? "unban" : "ban", ).then((res) => { setTakeAction(false); if ( @@ -1094,7 +1094,7 @@ export const RoomSettingsModal = () => { await takeActionCall( selectedChatID as string, user.id, - "mute" + "mute", ).then((res) => { setTakeAction(false); if ( @@ -1102,7 +1102,7 @@ export const RoomSettingsModal = () => { res?.status === 201 ) { toast.success( - "User Muted For a 5 minutes Successfully" + "User Muted For a 5 minutes Successfully", ); } @@ -1120,7 +1120,7 @@ export const RoomSettingsModal = () => { await takeActionCall( selectedChatID as string, user.id, - "kick" + "kick", ).then((res) => { setTakeAction(false); if ( @@ -1146,7 +1146,7 @@ export const RoomSettingsModal = () => { await takeActionCall( selectedChatID as string, user.id, - "setAdmin" + "setAdmin", ).then((res) => { setTakeAction(false); if ( @@ -1154,7 +1154,7 @@ export const RoomSettingsModal = () => { res?.status === 201 ) { toast.success( - "User have been set as Admin Successfully" + "User have been set as Admin Successfully", ); } }); @@ -1221,7 +1221,7 @@ export const RoomSettingsModal = () => { currentRoom?.id!, selectedOption === RoomType.protected ? RoomPassword - : undefined + : undefined, ).then((res) => { if (res?.status !== 200 && res?.status !== 201) { resetModalState(); @@ -1269,7 +1269,7 @@ export const ExploreRoomsModal = () => { window.history.pushState( "", document.title, - window.location.pathname + window.location.search + window.location.pathname + window.location.search, ); modalState.setShowExploreModal(false); }; @@ -1297,19 +1297,16 @@ export const ExploreRoomsModal = () => { name: string; type: string; }) => { - //eslint-disable-next-line - { - rooms.push({ - id: room.id, - name: room.name, - type: RoomType[room.type as keyof typeof RoomType], - messages: [], - usersId: [], - isOwner: room.is_owner, - isAdmin: room.is_admin, - }); - } - } + rooms.push({ + id: room.id, + name: room.name, + type: RoomType[room.type as keyof typeof RoomType], + messages: [], + usersId: [], + isOwner: room.is_owner, + isAdmin: room.is_admin, + }); + }, ); setIsLoading(false); if (res.data.length > 0) { @@ -1349,8 +1346,8 @@ export const ExploreRoomsModal = () => { {ChatRooms.filter( (room) => recentRooms.recentRooms.find( - (recentRoom) => recentRoom.id === room.id - ) === undefined + (recentRoom) => recentRoom.id === room.id, + ) === undefined, ).map((room) => (
    { SelectedRoomID, selectedOption === RoomType.protected ? RoomPassword - : undefined + : undefined, ).then((res) => { recentRooms.setIsLoading(false); if (res?.status !== 200 && res?.status !== 201) { @@ -1437,7 +1434,7 @@ export const ExploreRoomsModal = () => { recentRooms.selectNewChatID("1"); recentRooms.changeChatType(ChatType.Room); recentRooms.setOnRoomsChange( - !recentRooms.recentRoomsOnchange + !recentRooms.recentRoomsOnchange, ); resetModalState(); diff --git a/frontend/code/src/Components/Chat/Components/UserToUserChat.tsx b/frontend/code/src/Components/Chat/Components/UserToUserChat.tsx index e0166bc..da14789 100644 --- a/frontend/code/src/Components/Chat/Components/UserToUserChat.tsx +++ b/frontend/code/src/Components/Chat/Components/UserToUserChat.tsx @@ -29,9 +29,6 @@ export const UserToUserChat = () => { avatar: extractedData.avatar, bio: extractedData.bio, }); - } else { - // navigator("/chat"); - // toast.error("Error getting room members"); } }); } catch (error) { @@ -63,55 +60,3 @@ export const UserToUserChat = () => { ); }; - -
    - - - - - - -
    -
    -
    -
    -
    - Avatar Tailwind CSS Component -
    -
    - {/*
    {user.name}
    */} -
    -
    - -
      -
    • - Block -
    • -
    • - - invite for a Pong Game - -
    • -
    • - - Show User Info - -
    • -
    -
    -
    -
    -
    ; diff --git a/frontend/code/src/Components/Chat/Components/tools/utils.ts b/frontend/code/src/Components/Chat/Components/tools/utils.ts index 562adbe..1e0a34a 100644 --- a/frontend/code/src/Components/Chat/Components/tools/utils.ts +++ b/frontend/code/src/Components/Chat/Components/tools/utils.ts @@ -2,7 +2,7 @@ export const formatTime = (backendDate: string) => { const currentDate = new Date(); const date = new Date(backendDate); const day = date.getDate(); - const month = date.toLocaleString('en-US', { month: 'short' }); + const month = date.toLocaleString("en-US", { month: "short" }); const hours = date.getHours(); const minutes = date.getMinutes(); const ampm = hours >= 12 ? " PM" : " AM"; @@ -14,4 +14,4 @@ export const formatTime = (backendDate: string) => { } else { return `${day} ${month} ${formattedHours}:${formattedMinutes}${ampm}`; } -} +}; diff --git a/frontend/code/src/Components/Chat/Controllers/RoomChatControllers.tsx b/frontend/code/src/Components/Chat/Controllers/RoomChatControllers.tsx index 52e559d..fd0452c 100644 --- a/frontend/code/src/Components/Chat/Controllers/RoomChatControllers.tsx +++ b/frontend/code/src/Components/Chat/Controllers/RoomChatControllers.tsx @@ -120,7 +120,7 @@ export const useChatStore = create()((set) => ({ setMessageAsFailed: (id: string) => set((state) => { const messageIndex = state.currentMessages.findIndex( - (message) => message.id === id + (message) => message.id === id, ); if (messageIndex !== -1) { state.currentMessages[messageIndex].isFailed = true; @@ -144,7 +144,9 @@ export const useChatStore = create()((set) => ({ updateTransientMessage: (message: Message, clientMessageId: string) => set((state) => { - const newCurrentMessages = state.currentMessages.filter((e) => e.clientMessageId !== clientMessageId); + const newCurrentMessages = state.currentMessages.filter( + (e) => e.clientMessageId !== clientMessageId, + ); state.currentMessages = [message, ...newCurrentMessages]; return { ...state }; @@ -155,7 +157,7 @@ export const useChatStore = create()((set) => ({ state.currentMessages = state.currentMessages.filter(cb); return { ...state }; - }) + }); }, fillCurrentMessages: (messages: Message[]) => @@ -172,12 +174,12 @@ export const useChatStore = create()((set) => ({ } state.recentRooms = [...chatRooms]; - if (state.recentRooms.length > 0) + if (state.recentRooms.length > 0) { state.selectedChatID = state.recentRooms[0].id; - else state.selectedChatID = "1"; + } else { + state.selectedChatID = "1"; + } state.recentRoomsOnchange = !state.recentRoomsOnchange; - // state.selectedChatType = ChatType.Chat; - // state.selectNewChatID(state.recentDms[0].id ?? "1"); state.selectNewChatID("1"); return { ...state }; @@ -222,7 +224,6 @@ export const useChatStore = create()((set) => ({ isOwner: true, isAdmin: true, }; - // state.selectedChatID = id; chatRooms.push(newRoom); state.recentRooms = [...chatRooms]; diff --git a/frontend/code/src/Components/Chat/Services/ChatServices.ts b/frontend/code/src/Components/Chat/Services/ChatServices.ts index 25614d8..df07d87 100644 --- a/frontend/code/src/Components/Chat/Services/ChatServices.ts +++ b/frontend/code/src/Components/Chat/Services/ChatServices.ts @@ -8,7 +8,6 @@ export const createNewRoomCall = async ( secondMember?: string, ) => { try { - const response = await api.post("/rooms/create", { name: name, type: type, @@ -21,18 +20,13 @@ export const createNewRoomCall = async ( } }; - - - export const updateRoomCall = async ( name: string, type: string, roomId: string, password?: string, - ) => { try { - const response = await api.post("/rooms/update", { name: name, type: type, @@ -43,56 +37,42 @@ export const updateRoomCall = async ( } catch (e: any) { toast.error(e.response.data.message); } - }; - export const fetchRoomsCall = async ( offset: number, limit: number, joined: boolean, - ) => { - try { - const response = await api.get(`/rooms`, - { params: { offset: offset, limit: limit, joined: joined } }); + const response = await api.get(`/rooms`, { + params: { offset: offset, limit: limit, joined: joined }, + }); return response; } catch (e: any) { // Do nothing } +}; -} - -export const fetchDmsCall = async ( - offset: number, - limit: number, - -) => { +export const fetchDmsCall = async (offset: number, limit: number) => { try { - const response = await api.get(`/rooms/dms`, - { params: { offset: offset, limit: limit } }); + const response = await api.get(`/rooms/dms`, { + params: { offset: offset, limit: limit }, + }); return response; } catch (e: any) { // Do nothing } +}; -} - - -export const getDM = async ( - id: string -) => { +export const getDM = async (id: string) => { try { - const response = await api.get(`/rooms/dm/${id}`, - ); + const response = await api.get(`/rooms/dm/${id}`); return response; } catch (e: any) { // Do nothing } - -} - +}; export const getRoomMembersCall = async ( id: string, @@ -100,23 +80,17 @@ export const getRoomMembersCall = async ( limit: number, ) => { try { - const response = await api.get(`/rooms/${id}/members`, - { params: { offset: offset, limit: limit } }); + const response = await api.get(`/rooms/${id}/members`, { + params: { offset: offset, limit: limit }, + }); return response; } catch (e: any) { // Do nothing } +}; -} - - -export const joinRoomCall = async ( - roomId: string, - password?: string, - -) => { +export const joinRoomCall = async (roomId: string, password?: string) => { try { - const response = await api.post("/rooms/join", { roomId: roomId, password: password, @@ -125,15 +99,10 @@ export const joinRoomCall = async ( } catch (e: any) { toast.error(e.response.data.message); } -} - - -export const leaveRoomCall = async ( - roomId: string, +}; -) => { +export const leaveRoomCall = async (roomId: string) => { try { - const response = await api.post("/rooms/leave", { roomId: roomId, }); @@ -141,8 +110,7 @@ export const leaveRoomCall = async ( } catch (e: any) { toast.error(e.response.data.message); } - -} +}; export const takeActionCall = async ( roomId: string, @@ -158,43 +126,26 @@ export const takeActionCall = async ( } catch (e: any) { toast.error(e.response.data.message); } +}; -} - -export const DeleteRoomCall = async ( - roomId: string, - -) => { +export const DeleteRoomCall = async (roomId: string) => { try { - const response = await api.post("/rooms/delete", { roomId: roomId, - }); return response; } catch (e: any) { toast.error(e.response.data.message); } -} - -// unused -export const getFriendsCall = async ( - offset: number, - limit: number, - - -) => { +}; +export const getFriendsCall = async (offset: number, limit: number) => { try { - const response = await api.get(`/friends/list`, - { params: { offset: offset, limit: limit } }); + const response = await api.get(`/friends/list`, { + params: { offset: offset, limit: limit }, + }); return response; } catch (e: any) { // Do nothing } - -} - - - - +}; diff --git a/frontend/code/src/Components/Chat/Services/FriendsServices.ts b/frontend/code/src/Components/Chat/Services/FriendsServices.ts index ca87eaf..a3b4179 100644 --- a/frontend/code/src/Components/Chat/Services/FriendsServices.ts +++ b/frontend/code/src/Components/Chat/Services/FriendsServices.ts @@ -1,28 +1,20 @@ import api from "../../../Api/base"; -export const getBlockedCall = async ( - offset: number, - limit: number, - - -) => { - +export const getBlockedCall = async (offset: number, limit: number) => { try { - const response = await api.get(`/friends/blocklist`, - { params: { offset: offset, limit: limit } }); + const response = await api.get(`/friends/blocklist`, { + params: { offset: offset, limit: limit }, + }); return response; } catch (e: any) { // Do nothing } +}; -} - -export const unblockCall = async ( - friendId: string -) => { +export const unblockCall = async (friendId: string) => { try { const response = await api.post("/friends/unblock", { - friendId: friendId + friendId: friendId, }); return response; } catch (e: any) { @@ -30,16 +22,13 @@ export const unblockCall = async ( } }; -export const blockUserCall = async ( - friendId: string -) => { +export const blockUserCall = async (friendId: string) => { try { const response = await api.post("/friends/block", { - friendId: friendId + friendId: friendId, }); return response; } catch (e: any) { // Do nothing } -} - +}; diff --git a/frontend/code/src/Components/Chat/Services/MessagesServices.ts b/frontend/code/src/Components/Chat/Services/MessagesServices.ts index 6e19229..f5c068a 100644 --- a/frontend/code/src/Components/Chat/Services/MessagesServices.ts +++ b/frontend/code/src/Components/Chat/Services/MessagesServices.ts @@ -1,30 +1,33 @@ - import api from "../../../Api/base"; export const getRoomMessagesCall = async ( - id: string, - offset: number, - limit: number, + id: string, + offset: number, + limit: number, ) => { - try { - const response = await api.get(`/messages/room/${id}/`, { params: { offset: offset, limit: limit } }); - return response; - } catch (e: any) { - return e.response; - } -} + try { + const response = await api.get(`/messages/room/${id}/`, { + params: { offset: offset, limit: limit }, + }); + return response; + } catch (e: any) { + return e.response; + } +}; export const sendMessageCall = async ( - id: string, - content: string, - clientMessageId?: string + id: string, + content: string, + clientMessageId?: string, ) => { - try { - const response = await api.post(`messages/room/${id}`, - { content, clientMessageId }, { params: { id: id } } - ); - return response; - } catch (e: any) { - return e.response; - } -} + try { + const response = await api.post( + `messages/room/${id}`, + { content, clientMessageId }, + { params: { id: id } }, + ); + return response; + } catch (e: any) { + return e.response; + } +}; diff --git a/frontend/code/src/Components/Chat/Services/SocketsServices.ts b/frontend/code/src/Components/Chat/Services/SocketsServices.ts index 188ce9b..f33b6f9 100644 --- a/frontend/code/src/Components/Chat/Services/SocketsServices.ts +++ b/frontend/code/src/Components/Chat/Services/SocketsServices.ts @@ -1,5 +1,5 @@ -import { io } from 'socket.io-client'; -import { create } from 'zustand' +import { io } from "socket.io-client"; +import { create } from "zustand"; interface SocketStore { socket: any; @@ -17,28 +17,30 @@ export const useSocketStore = create((set, get) => ({ set((state) => { if (state.socket === null) { newSocket = io("http://test.reversablecode.com:3004", { - transports: ['websocket'], - 'reconnection': true, - 'reconnectionDelay': 1000, - 'reconnectionDelayMax': 1000, - 'reconnectionAttempts': 5 + transports: ["websocket"], + reconnection: true, + reconnectionDelay: 1000, + reconnectionDelayMax: 1000, + reconnectionAttempts: 5, }); // Set socket set({ ...state, socket: newSocket }); - newSocket.on('connect', () => { + newSocket.on("connect", () => { // Set connected state set({ ...state, connected: true }); }); - newSocket.on('connect_error', async () => { - await new Promise((resolve) => setTimeout(() => { - // Set connected state - set({ ...state, connected: false }); - newSocket.connect(); - resolve(newSocket); - }, 1000)) + newSocket.on("connect_error", async () => { + await new Promise((resolve) => + setTimeout(() => { + // Set connected state + set({ ...state, connected: false }); + newSocket.connect(); + resolve(newSocket); + }, 1000), + ); }); return { ...state, socket: newSocket }; @@ -48,6 +50,5 @@ export const useSocketStore = create((set, get) => ({ }); return newSocket; - } -})) - + }, +})); diff --git a/frontend/code/src/Components/Chat/index.tsx b/frontend/code/src/Components/Chat/index.tsx index 9da886a..6a60473 100644 --- a/frontend/code/src/Components/Chat/index.tsx +++ b/frontend/code/src/Components/Chat/index.tsx @@ -65,7 +65,7 @@ export const Chat = () => { ? "w-4/5 lg:w-4/12 max-w-lg " : "w-4/5 lg:w-4/12 max-w-lg ", "absolute lg:relative h-full min-w-[360px] lg:border-r-2 border-base-200", - "z-20 transition-transform transform data-[mobile-show=true]:translate-x-0 data-[mobile-show=false]:-translate-x-[1000px] lg:!transform-none lg:!transition-none duration-300" + "z-20 transition-transform transform data-[mobile-show=true]:translate-x-0 data-[mobile-show=false]:-translate-x-[1000px] lg:!transform-none lg:!transition-none duration-300", )} data-mobile-show={showChatRooms} > @@ -126,10 +126,9 @@ export const UserPreviewCard: React.FC = ({ if (res?.status === 200 || res?.status === 201) { const extractedData = res.data; setIsLoading(false); - setUsers(extractedData); } - } + }, ); } } catch (error) { diff --git a/frontend/code/src/Components/Error/Assets/Font.tsx b/frontend/code/src/Components/Error/Assets/Font.tsx index 9c5322c..dfba0b7 100644 --- a/frontend/code/src/Components/Error/Assets/Font.tsx +++ b/frontend/code/src/Components/Error/Assets/Font.tsx @@ -1,13 +1,38 @@ - - export const Font = () => { - return ( - - - - - - - - ) -} \ No newline at end of file + return ( + + + + + + + ); +}; diff --git a/frontend/code/src/Components/Error/index.tsx b/frontend/code/src/Components/Error/index.tsx index d9dd299..7f10f30 100644 --- a/frontend/code/src/Components/Error/index.tsx +++ b/frontend/code/src/Components/Error/index.tsx @@ -1,12 +1,13 @@ -import { Font } from './Assets/Font' +import { Font } from "./Assets/Font"; -export const Error = () => -{ - return ( -
    - -
    -

    Page Not Found

    -
    - ) -} \ No newline at end of file +export const Error = () => { + return ( +
    + +
    +

    + Page Not Found +

    +
    + ); +}; diff --git a/frontend/code/src/Components/FirstLogin/UploadAvatar.tsx b/frontend/code/src/Components/FirstLogin/UploadAvatar.tsx index 5d1eb50..cf86ebc 100644 --- a/frontend/code/src/Components/FirstLogin/UploadAvatar.tsx +++ b/frontend/code/src/Components/FirstLogin/UploadAvatar.tsx @@ -25,7 +25,14 @@ const payload_objects = [ "phone", "discreption", ]; -const data_names = ["First name", "Last name", "Email", "Username", "Phone", "Bio"]; +const data_names = [ + "First name", + "Last name", + "Email", + "Username", + "Phone", + "Bio", +]; export const UploadAvatar = () => { const userStore = useUserStore(); const navigate = useNavigate(); @@ -42,7 +49,7 @@ export const UploadAvatar = () => { } catch (e) {} }; const handleError = (errors: any) => { - //eslint-disable-next-line + // eslint-disable-next-line payload_objects.map((item: any, index: number) => { if (errors[`${item}`]?.type === "required") toast.error(`${data_names[index]} ${ERROR_MESSAGES[0]} `); diff --git a/frontend/code/src/Components/FirstLogin/UploadLogic.tsx b/frontend/code/src/Components/FirstLogin/UploadLogic.tsx index 75cd826..f471a6a 100644 --- a/frontend/code/src/Components/FirstLogin/UploadLogic.tsx +++ b/frontend/code/src/Components/FirstLogin/UploadLogic.tsx @@ -45,7 +45,7 @@ export const UploadLogic = () => { success: "New Avatar Saved", error: "Error On Uploading image", }, - { position: "top-center", className: "h-20", duration: 2000 } + { position: "top-center", className: "h-20", duration: 2000 }, ); }} ref={inputRef} diff --git a/frontend/code/src/Components/Game/States/GameState.ts b/frontend/code/src/Components/Game/States/GameState.ts index a5c9f11..e9c0805 100644 --- a/frontend/code/src/Components/Game/States/GameState.ts +++ b/frontend/code/src/Components/Game/States/GameState.ts @@ -1,59 +1,58 @@ -import { create } from 'zustand' +import { create } from "zustand"; type GameStateType = { - width:number; - height:number; - mobile:boolean; - ball:{ - x:number, - y:number, - size:number, - p1Score:number, - p2Score:number, + width: number; + height: number; + mobile: boolean; + ball: { + x: number; + y: number; + size: number; + p1Score: number; + p2Score: number; }; - lPaddle:number; - rPaddle:number; - ballOwner:number; - p1:any; - p2:any; - side:boolean; - end:boolean; -} + lPaddle: number; + rPaddle: number; + ballOwner: number; + p1: any; + p2: any; + side: boolean; + end: boolean; +}; type GameActions = { - setHeight : (h: GameStateType['height']) => void; - setWidth : (w : GameStateType['width']) => void; - setLPaddle : (lp : GameStateType['lPaddle']) => void; - setRPaddle : (rp : GameStateType['rPaddle']) => void; - setBall : (pos : GameStateType['ball']) => void; - setMobile : (isMobile : GameStateType['mobile']) => void; - setP1 : (p1 : GameStateType['p1']) => void; - setP2 : (p2 : GameStateType['p2']) => void; - setSide : (side : GameStateType['side']) => void; - setEnd : (end : GameStateType['end']) => void; -} + setHeight: (h: GameStateType["height"]) => void; + setWidth: (w: GameStateType["width"]) => void; + setLPaddle: (lp: GameStateType["lPaddle"]) => void; + setRPaddle: (rp: GameStateType["rPaddle"]) => void; + setBall: (pos: GameStateType["ball"]) => void; + setMobile: (isMobile: GameStateType["mobile"]) => void; + setP1: (p1: GameStateType["p1"]) => void; + setP2: (p2: GameStateType["p2"]) => void; + setSide: (side: GameStateType["side"]) => void; + setEnd: (end: GameStateType["end"]) => void; +}; -export const useGameState = create((set)=> ({ - width : 0, - height : 0, - mobile : false, - ball : {x: 0,y:0,size:0,p1Score:0,p2Score:0}, - lPaddle : 0, - rPaddle : 0, - ballOwner:-1, - p1:null, - p2:null, - side:false, - end:true, - setHeight : (h) => set(() => ({height : h})), - setWidth : (w) => set(() => ({width : w})), - setLPaddle : (lp) => set(() => ({lPaddle : lp})), - setRPaddle : (rp) => set(() => ({rPaddle : rp})), - setMobile : (isMobile ) => set(() => ({mobile:isMobile})), - setBall : (pos) => set(() => ({ball:pos})), - setP1 : (p1) => set(() => ({p1:p1})), - setP2 : (p2) => set(() => ({p2:p2})), - setSide : (side) => set(() => ({side:side})), - setEnd : (end) => set(() => ({end:end})), - -})) \ No newline at end of file +export const useGameState = create((set) => ({ + width: 0, + height: 0, + mobile: false, + ball: { x: 0, y: 0, size: 0, p1Score: 0, p2Score: 0 }, + lPaddle: 0, + rPaddle: 0, + ballOwner: -1, + p1: null, + p2: null, + side: false, + end: true, + setHeight: (h) => set(() => ({ height: h })), + setWidth: (w) => set(() => ({ width: w })), + setLPaddle: (lp) => set(() => ({ lPaddle: lp })), + setRPaddle: (rp) => set(() => ({ rPaddle: rp })), + setMobile: (isMobile) => set(() => ({ mobile: isMobile })), + setBall: (pos) => set(() => ({ ball: pos })), + setP1: (p1) => set(() => ({ p1: p1 })), + setP2: (p2) => set(() => ({ p2: p2 })), + setSide: (side) => set(() => ({ side: side })), + setEnd: (end) => set(() => ({ end: end })), +})); diff --git a/frontend/code/src/Components/Game/index.tsx b/frontend/code/src/Components/Game/index.tsx index 5c58965..4b5ab1f 100644 --- a/frontend/code/src/Components/Game/index.tsx +++ b/frontend/code/src/Components/Game/index.tsx @@ -1,14 +1,13 @@ -import { useCallback, useEffect, useState } from "react" -import { Rect, Stage, Layer, Circle, Line } from "react-konva" -import { BsFillArrowRightCircleFill, BsFillArrowLeftCircleFill } from "react-icons/bs"; +import { useCallback, useEffect, useState } from "react"; +import { Rect, Stage, Layer, Circle, Line } from "react-konva"; +import { + BsFillArrowRightCircleFill, + BsFillArrowLeftCircleFill, +} from "react-icons/bs"; import { useGameState } from "./States/GameState"; import { useSocketStore } from "../Chat/Services/SocketsServices"; import { useNavigate } from "react-router-dom"; - - - - const DURATION = 20; type Cords = { x: number; @@ -16,7 +15,7 @@ type Cords = { ballsize: number; p1Score: number; p2Score: number; -} +}; const throttle = (function () { let timeout: any = undefined; @@ -27,16 +26,15 @@ const throttle = (function () { timeout = undefined; }, DURATION); } - } + }; })(); - function throttlify(callback: any) { return function throttlified(event: any) { throttle(() => { callback(event); }); - } + }; } export const Game = () => { @@ -44,151 +42,221 @@ export const Game = () => { const socketStore = useSocketStore(); const [level, setLevel] = useState(1); const [t, setT] = useState(0); - const navigate = useNavigate() + const navigate = useNavigate(); const leave = useCallback(() => { - socketStore.socket?.emit("leave") + socketStore.socket?.emit("leave"); gameState.setEnd(true); // eslint-disable-next-line - }, []) + }, []); const handleMove = throttlify((e: any) => { socketStore.socket?.emit("mouse", e.evt.layerY); - }) + }); const ArrowUp = () => { socketStore.socket?.emit("up"); socketStore.socket?.off("up"); - } + }; const ArrowDown = () => { - socketStore.socket?.emit("down") + socketStore.socket?.emit("down"); socketStore.socket?.off("down"); - } + }; useEffect(() => { - socketStore.socket?.on("level", (l: number) => { setLevel(l) }) - socketStore.socket?.on("t", (t: number) => { setT(t) }) + socketStore.socket?.on("level", (l: number) => { + setLevel(l); + }); + socketStore.socket?.on("t", (t: number) => { + setT(t); + }); socketStore.socket?.on("game.end", () => { - gameState.setEnd(true) - }) - document.addEventListener('keydown', (event) => { - if (event.key === "ArrowUp") - socketStore.socket?.emit("up"); - if (event.key === "ArrowDown") - socketStore.socket?.emit("down") - }) + gameState.setEnd(true); + }); + document.addEventListener("keydown", (event) => { + if (event.key === "ArrowUp") socketStore.socket?.emit("up"); + if (event.key === "ArrowDown") socketStore.socket?.emit("down"); + }); socketStore.socket?.on("ball", (cord: Cords) => { - gameState.setBall({ x: cord.x, y: cord.y, size: cord.ballsize, p1Score: cord.p1Score, p2Score: cord.p2Score }) - }) + gameState.setBall({ + x: cord.x, + y: cord.y, + size: cord.ballsize, + p1Score: cord.p1Score, + p2Score: cord.p2Score, + }); + }); socketStore.socket?.on("paddle", (paddles: any) => { gameState.setLPaddle(paddles.p1PaddleY); gameState.setRPaddle(paddles.p2PaddleY); - if (gameState?.side !== paddles.side) - gameState.setSide(paddles.side); - }) + if (gameState?.side !== paddles.side) gameState.setSide(paddles.side); + }); socketStore.socket?.on("screen Error", () => { - navigate("/home") - }) + navigate("/home"); + }); socketStore.socket?.on("players", (players: any) => { gameState.setP1(players[0]); gameState.setP2(players[1]); - }) + }); return () => { socketStore.socket?.off("ball"); socketStore.socket?.off("mouse"); socketStore.socket?.off("down"); socketStore.socket?.off("up"); - socketStore.socket?.off("leave") - socketStore.socket?.off("level") - socketStore.socket?.off("t") - socketStore.socket?.off("game.end") - - window.removeEventListener("keydown", () => { }); + socketStore.socket?.off("leave"); + socketStore.socket?.off("level"); + socketStore.socket?.off("t"); + socketStore.socket?.off("game.end"); - } + window.removeEventListener("keydown", () => {}); + }; // eslint-disable-next-line - }, []) + }, []); /* eslint-disable */ useEffect(() => { - if (!gameState.p1) - navigate("/home") - const divh = document.getElementById('Game')?.offsetHeight - const divw = document.getElementById('Game')?.offsetWidth - socketStore.socket?.emit("screen", { h: divh, w: divw }) + if (!gameState.p1) navigate("/home"); + const divh = document.getElementById("Game")?.offsetHeight; + const divw = document.getElementById("Game")?.offsetWidth; + socketStore.socket?.emit("screen", { h: divh, w: divw }); gameState.setEnd(false); - if (divw) { divw <= 742 ? gameState.setMobile(true) : gameState.setMobile(false) } - window.addEventListener('resize', () => { + if (divw) { + divw <= 742 ? gameState.setMobile(true) : gameState.setMobile(false); + } + window.addEventListener("resize", () => { gameState.setEnd(false); - const divh = document.getElementById('Game')?.offsetHeight - const divw = document.getElementById('Game')?.offsetWidth + const divh = document.getElementById("Game")?.offsetHeight; + const divw = document.getElementById("Game")?.offsetWidth; const aspectRatio = 16 / 9; const newWidth = divw ?? 0; const newHeight = newWidth / aspectRatio; - socketStore.socket?.emit("screen", { h: newHeight, w: newWidth }) + socketStore.socket?.emit("screen", { h: newHeight, w: newWidth }); if (divh) gameState.setHeight(newHeight); - if (divw) { gameState.setWidth(divw); divw <= 742 ? gameState.setMobile(true) : gameState.setMobile(false); } + if (divw) { + gameState.setWidth(divw); + divw <= 742 ? gameState.setMobile(true) : gameState.setMobile(false); + } }); return () => { socketStore.socket?.off("screen"); - window.removeEventListener("resize", () => { }); - - } + window.removeEventListener("resize", () => {}); + }; // disable eslit next line - }, []) + }, []); useEffect(() => { - const divh = document.getElementById('Game')?.offsetHeight - const divw = document.getElementById('Game')?.offsetWidth + const divh = document.getElementById("Game")?.offsetHeight; + const divw = document.getElementById("Game")?.offsetWidth; const aspectRatio = 16 / 9; const newWidth = divw ?? 0; const newHeight = newWidth / aspectRatio; if (divh) gameState.setHeight(newHeight); if (divw) gameState.setWidth(divw); - - }, [gameState.width, gameState.height]) + }, [gameState.width, gameState.height]); return ( -
    +
    - - {gameState.ball.p1Score} + + + {gameState.ball.p1Score} +
    - {gameState?.ball.p2Score} - - + + {gameState?.ball.p2Score} + +
    - - +
    -
    {t > 0 ? (`next level start after ${t}`) : (`level ${level}`)}
    - +
    + {t > 0 ? `next level start after ${t}` : `level ${level}`} +
    -
    - - - - - - - +
    + + + + + + + - -
    {gameState.mobile && (
    - - + +
    - ) - - } + )}
    - - ) -} + ); +}; diff --git a/frontend/code/src/Components/Home/LeaderBoard.tsx b/frontend/code/src/Components/Home/LeaderBoard.tsx index 089ede0..ecec368 100644 --- a/frontend/code/src/Components/Home/LeaderBoard.tsx +++ b/frontend/code/src/Components/Home/LeaderBoard.tsx @@ -3,7 +3,7 @@ import InfiniteScroll from "react-infinite-scroll-component"; import { Link } from "react-router-dom"; import toast from "react-hot-toast"; -import { Chart } from './assets/Chart'; +import { Chart } from "./assets/Chart"; import { Trophy } from "./assets/Trophy"; import { Daimond } from "./assets/Daimond"; import { Logo } from "../Layout/Assets/Logo"; @@ -13,141 +13,143 @@ import { NullPlaceHolder } from "../Chat/Components/RoomChatHelpers"; import api from "../../Api/base"; export const LeaderBoard = () => { - const [users, setUsers] = useState([]); - const [loading, setLoading] = useState(true); + const [users, setUsers] = useState([]); + const [loading, setLoading] = useState(true); - const page = useRef(0); - const hasMoreItems = useRef(true); - const [fetching, setFetching] = useState(false); - const [nextPageUrl, setNextPageUrl] = useState("/leaderboard?offset=0&limit=20"); + const page = useRef(0); + const hasMoreItems = useRef(true); + const [fetching, setFetching] = useState(false); + const [nextPageUrl, setNextPageUrl] = useState( + "/leaderboard?offset=0&limit=20", + ); - const fetchItems = useCallback(async () => { - if (!nextPageUrl) return; - if (fetching) return; + const fetchItems = useCallback(async () => { + if (!nextPageUrl) return; + if (fetching) return; - setFetching(true); + setFetching(true); - try { - const newdata = await api.get(nextPageUrl); - // End of pagination - if (!newdata.data || newdata.data.length < 20) { - newdata.data && setUsers([...users, ...newdata.data]); - setNextPageUrl(null); - // Update hasMoreItems state - hasMoreItems.current = false; - return; - } - // Prepare next page - setUsers([...users, ...newdata.data]); - setNextPageUrl(`/leaderboard?offset=${page.current}&limit=20`); - page.current += 20; - // Update hasMoreItems state - hasMoreItems.current = true; - } catch (e) { - toast.error("Can't get leadeboard"); - } finally { - setLoading(false); - setFetching(false); - } - }, [users, fetching, nextPageUrl]); + try { + const newdata = await api.get(nextPageUrl); + // End of pagination + if (!newdata.data || newdata.data.length < 20) { + newdata.data && setUsers([...users, ...newdata.data]); + setNextPageUrl(null); + // Update hasMoreItems state + hasMoreItems.current = false; + return; + } + // Prepare next page + setUsers([...users, ...newdata.data]); + setNextPageUrl(`/leaderboard?offset=${page.current}&limit=20`); + page.current += 20; + // Update hasMoreItems state + hasMoreItems.current = true; + } catch (e) { + toast.error("Can't get leadeboard"); + } finally { + setLoading(false); + setFetching(false); + } + }, [users, fetching, nextPageUrl]); - useEffect(() => { - fetchItems(); - page.current += 20; - //eslint-disable-next-line - }, []); + useEffect(() => { + fetchItems(); + page.current += 20; + // eslint-disable-next-line + }, []); - return ( -
    -
    - Leader Board -
    + return ( +
    +
    + Leader Board +
    - {(users.length > 0) || loading ? ( -
    - - -
    - } - endMessage={ -
    - No more results! -
    - } - hasMore={hasMoreItems.current} - scrollableTarget="scrollTarget" - style={{ overflow: "auto", height: "100%" }} + {users.length > 0 || loading ? ( +
    + + +
    + } + endMessage={ +
    + No more results! +
    + } + hasMore={hasMoreItems.current} + scrollableTarget="scrollTarget" + style={{ overflow: "auto", height: "100%" }} + > + + + + + + + + + + {!loading && + users.map((x: any, index: number) => ( + -
    +
    + Place +
    +
    +
    + User +
    +
    +
    + Score +
    +
    - - - - - - - - - {!loading && - users.map((x: any, index: number) => ( - - - - - - ))} - -
    -
    - Place -
    -
    -
    - User -
    -
    -
    - Score -
    -
    -
    - {index + 1} -
    -
    -
    - -
    - {x?.Username} -
    - - {x?.Username} - -
    -
    - -
    -
    -
    - {x?.wins} -
    -
    - -
    - ) : ( -
    - -
    - )} + +
    + {index + 1} +
    + + +
    + +
    + {x?.Username} +
    + + {x?.Username} + +
    +
    + +
    + + +
    + {x?.wins} +
    + + + ))} + + + +
    + ) : ( +
    +
    - ) -} + )} +
    + ); +}; diff --git a/frontend/code/src/Components/Home/assets/Chart.tsx b/frontend/code/src/Components/Home/assets/Chart.tsx index 404dcd2..e9a5cd2 100644 --- a/frontend/code/src/Components/Home/assets/Chart.tsx +++ b/frontend/code/src/Components/Home/assets/Chart.tsx @@ -1,9 +1,16 @@ export const Chart = () => { - return ( - - - - - - ) -} + return ( + + + + ); +}; diff --git a/frontend/code/src/Components/Home/assets/Daimond.tsx b/frontend/code/src/Components/Home/assets/Daimond.tsx index f3c9d09..f802dc7 100644 --- a/frontend/code/src/Components/Home/assets/Daimond.tsx +++ b/frontend/code/src/Components/Home/assets/Daimond.tsx @@ -1,11 +1,22 @@ -import type { HTMLAttributes } from "react" +import type { HTMLAttributes } from "react"; type DiamondProps = HTMLAttributes; export const Daimond = (props: DiamondProps) => { - return ( - - - - ) -} + return ( + + + + ); +}; diff --git a/frontend/code/src/Components/Home/assets/Trophy.tsx b/frontend/code/src/Components/Home/assets/Trophy.tsx index 7d9e5ba..3237080 100644 --- a/frontend/code/src/Components/Home/assets/Trophy.tsx +++ b/frontend/code/src/Components/Home/assets/Trophy.tsx @@ -1,11 +1,21 @@ -import type { HTMLAttributes } from "react" +import type { HTMLAttributes } from "react"; type TrophyProps = HTMLAttributes; export const Trophy = (props: TrophyProps) => { - return ( - - - - ) -} + return ( + + + + ); +}; diff --git a/frontend/code/src/Components/Home/index.tsx b/frontend/code/src/Components/Home/index.tsx index 7c8c943..2f4f5a7 100644 --- a/frontend/code/src/Components/Home/index.tsx +++ b/frontend/code/src/Components/Home/index.tsx @@ -19,8 +19,13 @@ export const Home = (): JSX.Element => { READY TO PLAY A GAME?
    - - PLAY NOW + + + PLAY NOW +
    diff --git a/frontend/code/src/Components/Layout/Assets/Alert.tsx b/frontend/code/src/Components/Layout/Assets/Alert.tsx index 37bc8b7..ca45e1b 100644 --- a/frontend/code/src/Components/Layout/Assets/Alert.tsx +++ b/frontend/code/src/Components/Layout/Assets/Alert.tsx @@ -21,13 +21,13 @@ export const Alert = () => { addFriend: "sent you a friend requst", acceptFriend: "accepted your friend request", }), - [] + [], ); const unread = useMemo(() => { if (!user?.notifications) return 0; return user.notifications.filter( - (notification: any) => !notification.is_read + (notification: any) => !notification.is_read, ).length; }, [user?.notifications]); @@ -39,46 +39,46 @@ export const Alert = () => { ) { if (notification.entity.authorId !== user.id) { toast.custom( - (t) => ( - // eslint-disable-next-line - (t.duration = 450), + (t) => ( -
    -
    -
    - avatar -
    -

    - message Received -

    -

    - {notification.entity.content} -

    + // eslint-disable-next-line + (t.duration = 450), + ( +
    +
    +
    + avatar +
    +

    + message Received +

    +

    + {notification.entity.content} +

    +
    -
    -
    - avatar +
    + avatar +
    -
    - ) - ) + ) + ), ); } - // } return; } @@ -88,7 +88,7 @@ export const Alert = () => { return () => { socketStore.socket?.off("notification"); }; - //eslint-disable-next-line + // eslint-disable-next-line }, [socketStore]); useEffect(() => { @@ -160,14 +160,14 @@ export const Alert = () => { key={notification.id} className={classNames( "flex flex-row justify-start text-xs gap-3 p-4 hover:cursor-pointer", - notification.is_read && "opacity-50" + notification.is_read && "opacity-50", )} onClick={async () => { try { navigate(`/profile/${notification.actorId}`); user.updateNotificationRead(notification.id); await api.post( - `/profile/read-notification/${notification.id}` + `/profile/read-notification/${notification.id}`, ); } catch (error) { toast.error("Something went wrong"); diff --git a/frontend/code/src/Components/Layout/Assets/Dash.tsx b/frontend/code/src/Components/Layout/Assets/Dash.tsx index 1f4f091..0524839 100644 --- a/frontend/code/src/Components/Layout/Assets/Dash.tsx +++ b/frontend/code/src/Components/Layout/Assets/Dash.tsx @@ -12,7 +12,7 @@ export const Dash = ({ selected, className, ...props }: DashProps) => { className={classNames( "h-10 w-10 hover:bg-secondary p-1 rounded-xl flex justify-center items-center hover:cursor-pointer", selected && "bg-secondary", - className + className, )} {...props} > diff --git a/frontend/code/src/Components/Layout/Assets/Game.tsx b/frontend/code/src/Components/Layout/Assets/Game.tsx index 47c1d05..c10a497 100644 --- a/frontend/code/src/Components/Layout/Assets/Game.tsx +++ b/frontend/code/src/Components/Layout/Assets/Game.tsx @@ -12,7 +12,7 @@ export const Game = ({ selected, className, ...props }: GameProps) => { className={classNames( "h-10 w-10 hover:bg-secondary rounded-xl flex justify-center items-center hover:cursor-pointer", selected && "bg-secondary", - className + className, )} {...props} > diff --git a/frontend/code/src/Components/Layout/Assets/Invitationacceptance.tsx b/frontend/code/src/Components/Layout/Assets/Invitationacceptance.tsx index 86c9b7e..4a8ce3b 100644 --- a/frontend/code/src/Components/Layout/Assets/Invitationacceptance.tsx +++ b/frontend/code/src/Components/Layout/Assets/Invitationacceptance.tsx @@ -31,7 +31,7 @@ export const InvitationWaiting = forwardRef( socketStore.socket?.off("game.declined"); socketStore.socket?.off("game.accepted"); }; - //eslint-disable-next-line + // eslint-disable-next-line }, [userStore.gameId, socketStore.socket, ref]); return ( diff --git a/frontend/code/src/Components/Layout/Assets/Invitationmodale.tsx b/frontend/code/src/Components/Layout/Assets/Invitationmodale.tsx index 1933295..f4ac303 100644 --- a/frontend/code/src/Components/Layout/Assets/Invitationmodale.tsx +++ b/frontend/code/src/Components/Layout/Assets/Invitationmodale.tsx @@ -37,7 +37,7 @@ export const InvitationGame = forwardRef((_, ref) => { return () => { socketStore.socket?.off("game.declined"); }; - //eslint-disable-next-line + // eslint-disable-next-line }, [userStore.inviterId, socketStore, ref]); return ( diff --git a/frontend/code/src/Components/Layout/Assets/Message.tsx b/frontend/code/src/Components/Layout/Assets/Message.tsx index 1fecb84..3341d03 100644 --- a/frontend/code/src/Components/Layout/Assets/Message.tsx +++ b/frontend/code/src/Components/Layout/Assets/Message.tsx @@ -12,7 +12,7 @@ export const Message = ({ selected, className, ...props }: MessageProps) => { className={classNames( "h-10 w-10 hover:bg-secondary rounded-xl flex justify-center items-center hover:cursor-pointer", selected && "bg-secondary", - className + className, )} {...props} > diff --git a/frontend/code/src/Components/Layout/Assets/Modal.tsx b/frontend/code/src/Components/Layout/Assets/Modal.tsx index 4832dec..e476a7e 100644 --- a/frontend/code/src/Components/Layout/Assets/Modal.tsx +++ b/frontend/code/src/Components/Layout/Assets/Modal.tsx @@ -1,96 +1,98 @@ -import { useSocketStore } from "../../Chat/Services/SocketsServices" +import { useSocketStore } from "../../Chat/Services/SocketsServices"; import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { useGameState } from "../../Game/States/GameState"; export const Modal = () => { - const gameState = useGameState(); - const [opacity , setOpacity] = useState(""); - const [resOpacity , setResOpacity] = useState(""); - const [result , setResutl] = useState(undefined); - const [status , setStatus] = useState(undefined); - const [timer , setTimer] = useState(undefined); - const [gameid , setGameId] = useState(undefined); - const socketStore = useSocketStore(); - const navigate = useNavigate(); - useEffect(() => { - if (socketStore.socket !== null){ - socketStore.socket?.on("game.launched" , (GameId:any) => { - setGameId(GameId.slice(5)) - }) - socketStore.socket?.on("timer",(msg:any) => { - msg !== 0 && setOpacity("opacity-100") - msg === 0 && setOpacity("opacity-0") - setTimer(msg / 1000) - if (timer === 5){ - navigate(`/Game/${gameid}`) - } - }) - socketStore.socket?.on("players", (players:any) => { - gameState.setP1(players[0]); - gameState.setP2(players[1]); - }) - socketStore.socket?.on("win" , (msg:string) => { - setResutl(msg) - setStatus("win"); - setResOpacity("opacity-100"); - let count = 2; - setTimer(count); - const inter = setInterval(() => { - setTimer(count); - --count; - if (count === -1){ - setResOpacity("opacity-0") - clearInterval(inter); - navigate("/home") - } - },1000) - - }) - socketStore.socket?.on("lose" , (msg:string) => { - setResutl(msg) - setStatus("lose"); - setResOpacity("opacity-100"); - let count = 2; - setTimer(count); - const inter = setInterval(() => { - setTimer(count); - --count; - if (count === -1){ - setResOpacity("opacity-0") - clearInterval(inter); - navigate("/home") - } - },1000) - - }) + const gameState = useGameState(); + const [opacity, setOpacity] = useState(""); + const [resOpacity, setResOpacity] = useState(""); + const [result, setResutl] = useState(undefined); + const [status, setStatus] = useState(undefined); + const [timer, setTimer] = useState(undefined); + const [gameid, setGameId] = useState(undefined); + const socketStore = useSocketStore(); + const navigate = useNavigate(); + useEffect(() => { + if (socketStore.socket !== null) { + socketStore.socket?.on("game.launched", (GameId: any) => { + setGameId(GameId.slice(5)); + }); + socketStore.socket?.on("timer", (msg: any) => { + msg !== 0 && setOpacity("opacity-100"); + msg === 0 && setOpacity("opacity-0"); + setTimer(msg / 1000); + if (timer === 5) { + navigate(`/Game/${gameid}`); + } + }); + socketStore.socket?.on("players", (players: any) => { + gameState.setP1(players[0]); + gameState.setP2(players[1]); + }); + socketStore.socket?.on("win", (msg: string) => { + setResutl(msg); + setStatus("win"); + setResOpacity("opacity-100"); + let count = 2; + setTimer(count); + const inter = setInterval(() => { + setTimer(count); + --count; + if (count === -1) { + setResOpacity("opacity-0"); + clearInterval(inter); + navigate("/home"); + } + }, 1000); + }); + socketStore.socket?.on("lose", (msg: string) => { + setResutl(msg); + setStatus("lose"); + setResOpacity("opacity-100"); + let count = 2; + setTimer(count); + const inter = setInterval(() => { + setTimer(count); + --count; + if (count === -1) { + setResOpacity("opacity-0"); + clearInterval(inter); + navigate("/home"); + } + }, 1000); + }); } return () => { - socketStore.socket?.off("lose") - socketStore.socket?.off("win") - socketStore.socket?.off("timer") - socketStore.socket?.off("game.launched") - socketStore.socket?.off("players") - } -// eslint-disable-next-line -},[timer]) - - return ( - - <> -
    -
    -

    Game Starting ....

    -

    Game Start In {timer}

    -
    -
    -
    -
    -

    You {status}

    -

    {result}

    -

    this window will be dismiss in {timer}

    + socketStore.socket?.off("lose"); + socketStore.socket?.off("win"); + socketStore.socket?.off("timer"); + socketStore.socket?.off("game.launched"); + socketStore.socket?.off("players"); + }; + // eslint-disable-next-line + }, [timer]); -
    -
    - - ) -} \ No newline at end of file + return ( + <> +
    +
    +

    Game Starting ....

    +

    + Game Start In {timer} +

    +
    +
    +
    +
    +

    You {status}

    +

    + {result}{" "} +

    +

    + this window will be dismiss in {timer}{" "} +

    +
    +
    + + ); +}; diff --git a/frontend/code/src/Components/Layout/Assets/Out.tsx b/frontend/code/src/Components/Layout/Assets/Out.tsx index ca221ea..3448807 100644 --- a/frontend/code/src/Components/Layout/Assets/Out.tsx +++ b/frontend/code/src/Components/Layout/Assets/Out.tsx @@ -2,31 +2,43 @@ import { classNames } from "../../../Utils/helpers"; import { useUserStore } from "../../../Stores/stores"; import { Link } from "react-router-dom"; - type OutProps = React.HTMLAttributes & { - selected?: boolean; - }; -export const Out = ({ selected, className, ...props} : OutProps) => { + selected?: boolean; +}; +export const Out = ({ selected, className, ...props }: OutProps) => { const user = useUserStore(); - return ( - <> - { process.env?.REACT_APP_LOGOUT && + return ( + <> + {process.env?.REACT_APP_LOGOUT && ( user.logout()} to={process.env.REACT_APP_LOGOUT}> -
    - - - +
    + + + -
    +
    - } - - - ) -} + )} + + ); +}; diff --git a/frontend/code/src/Components/Layout/Assets/Profile.tsx b/frontend/code/src/Components/Layout/Assets/Profile.tsx index 8528270..2ad189e 100644 --- a/frontend/code/src/Components/Layout/Assets/Profile.tsx +++ b/frontend/code/src/Components/Layout/Assets/Profile.tsx @@ -1,5 +1,5 @@ -import {Link} from 'react-router-dom' -import { useUserStore } from '../../../Stores/stores' +import { Link } from "react-router-dom"; +import { useUserStore } from "../../../Stores/stores"; import { classNames } from "../../../Utils/helpers"; type ProfileProps = React.HTMLAttributes & { @@ -7,22 +7,34 @@ type ProfileProps = React.HTMLAttributes & { }; export const Profile = ({ selected, className, ...props }: ProfileProps) => { - const userStore = useUserStore(); - return ( - + const userStore = useUserStore(); + return (
    -
    - - - +
    + + +
    diff --git a/frontend/code/src/Components/Layout/Assets/Search.tsx b/frontend/code/src/Components/Layout/Assets/Search.tsx index 347ff31..84b51dc 100644 --- a/frontend/code/src/Components/Layout/Assets/Search.tsx +++ b/frontend/code/src/Components/Layout/Assets/Search.tsx @@ -1,72 +1,87 @@ -import { useState, ChangeEvent, useEffect } from 'react' -import { BiSearch } from 'react-icons/bi' -import { Link } from 'react-router-dom' -import api from '../../../Api/base' -import toast from 'react-hot-toast' +import { useState, ChangeEvent, useEffect } from "react"; +import { BiSearch } from "react-icons/bi"; +import { Link } from "react-router-dom"; +import api from "../../../Api/base"; +import toast from "react-hot-toast"; function useDebounce(value: T, delay?: number): T { - const [debouncedValue, setDebouncedValue] = useState(value) + const [debouncedValue, setDebouncedValue] = useState(value); - useEffect(() => { - const timer = setTimeout(() => setDebouncedValue(value), delay || 500) + useEffect(() => { + const timer = setTimeout(() => setDebouncedValue(value), delay || 500); - return () => { - clearTimeout(timer) - } - }, [value, delay]) + return () => { + clearTimeout(timer); + }; + }, [value, delay]); - return debouncedValue + return debouncedValue; } export const Search = () => { - const [searchText, setSearchText] = useState(""); - const DebounceValue = useDebounce(searchText); - const [hidden, setHidden] = useState("hidden"); - const onSearchTextChange = (e: ChangeEvent) => setSearchText(e.target.value); - const [result, setResult] = useState([]); - useEffect(() => { - const search = async () => { - try { - const res = await api.get("/users/search", { params: { q: DebounceValue } }) - setResult(res.data) - res.data.length ? setHidden("") : setHidden("hidden") - } catch (error) { - toast.error("can't find anyone") - } - } - DebounceValue && search() - }, [DebounceValue]) - const clear = () => { - setHidden("hidden"); setSearchText(""); setResult([]); - } - return ( + const [searchText, setSearchText] = useState(""); + const DebounceValue = useDebounce(searchText); + const [hidden, setHidden] = useState("hidden"); + const onSearchTextChange = (e: ChangeEvent) => + setSearchText(e.target.value); + const [result, setResult] = useState([]); + useEffect(() => { + const search = async () => { + try { + const res = await api.get("/users/search", { + params: { q: DebounceValue }, + }); + setResult(res.data); + res.data.length ? setHidden("") : setHidden("hidden"); + } catch (error) { + toast.error("can't find anyone"); + } + }; + DebounceValue && search(); + }, [DebounceValue]); + const clear = () => { + setHidden("hidden"); + setSearchText(""); + setResult([]); + }; + return ( +
    + -
    - - - -
    -
      -
      - {result.map((item: any, index: number) => { - return ( - -
    • -
      -
      -
      - -
      -
      - {item.name.first} {item.name.last} -
      -
    • - - ) - }) - } - -
      -
    +
    + +
    +
      +
      + {result.map((item: any, index: number) => { + return ( + +
    • +
      +
      +
      + +
      +
      + + {item.name.first} {item.name.last} + +
      +
    • + + ); + })}
      - ) -} \ No newline at end of file +
    +
    + ); +}; diff --git a/frontend/code/src/Components/Layout/Assets/Settings.tsx b/frontend/code/src/Components/Layout/Assets/Settings.tsx index 27f414d..2283c35 100644 --- a/frontend/code/src/Components/Layout/Assets/Settings.tsx +++ b/frontend/code/src/Components/Layout/Assets/Settings.tsx @@ -11,7 +11,7 @@ export const Settings = ({ selected, className, ...props }: SettingsProps) => { className={classNames( "h-10 w-10 hover:bg-secondary rounded-xl flex justify-center text-center items-center hover:cursor-pointer", selected && "bg-secondary", - className + className, )} {...props} > diff --git a/frontend/code/src/Components/Layout/index.tsx b/frontend/code/src/Components/Layout/index.tsx index 11b3899..b2a6e51 100644 --- a/frontend/code/src/Components/Layout/index.tsx +++ b/frontend/code/src/Components/Layout/index.tsx @@ -8,7 +8,13 @@ import { Message } from "./Assets/Message"; import { Profile } from "./Assets/Profile"; import { Settings } from "./Assets/Settings"; import { Out } from "./Assets/Out"; -import { FC, PropsWithChildren, useEffect, useLayoutEffect, useRef } from "react"; +import { + FC, + PropsWithChildren, + useEffect, + useLayoutEffect, + useRef, +} from "react"; import { Outlet } from "react-router"; import { matchRoutes, useLocation } from "react-router-dom"; import { useUserStore } from "../../Stores/stores"; @@ -55,13 +61,13 @@ export const Layout: FC = (): JSX.Element => { useEffect(() => { if (gameStore.end === false && path !== "Game/:id") { socketStore.socket?.emit("leave"); - gameStore.setEnd(true) + gameStore.setEnd(true); } return () => { socketStore.socket?.off("leave"); - } + }; // eslint-disable-next-line - }, [path]) + }, [path]); useLayoutEffect(() => { const log = async () => { try { @@ -87,7 +93,7 @@ export const Layout: FC = (): JSX.Element => { return () => { socketStore.socket?.off("invitedToGame"); }; - //eslint-disable-next-line + // eslint-disable-next-line }, []); return ( @@ -97,7 +103,9 @@ export const Layout: FC = (): JSX.Element => { ) : (
    diff --git a/frontend/code/src/Components/Login/Assets/Button.tsx b/frontend/code/src/Components/Login/Assets/Button.tsx index cf940de..d464ae1 100644 --- a/frontend/code/src/Components/Login/Assets/Button.tsx +++ b/frontend/code/src/Components/Login/Assets/Button.tsx @@ -1,20 +1,40 @@ -export const Button = () =>{ - return ( - - - - - - - - - - +export const Button = () => { + return ( + + + + + + + + + + - + - - - - ) -} \ No newline at end of file + + + ); +}; diff --git a/frontend/code/src/Components/Login/index.tsx b/frontend/code/src/Components/Login/index.tsx index 78da7ea..ed4f714 100644 --- a/frontend/code/src/Components/Login/index.tsx +++ b/frontend/code/src/Components/Login/index.tsx @@ -1,55 +1,46 @@ -import { Link } from "react-router-dom"; -import pingpong from '../images/pingpong.svg' -import {Button} from './Assets/Button' +import { Link } from "react-router-dom"; +import pingpong from "../images/pingpong.svg"; +import { Button } from "./Assets/Button"; import { useUserStore } from "../../Stores/stores"; import { useNavigate } from "react-router-dom"; import { useLayoutEffect } from "react"; -// import { PageLoading } from '../Loading'; -// const FallBackLoading = () => { -// return ( -//
    -// -//
    -// ) -// } -export const Login = () => -{ - const userStore = useUserStore(); - const navigate = useNavigate(); - useLayoutEffect(() => { - const check = async() => { - try { - const loggedin = await userStore.login(); - if (loggedin) - navigate("/home") - } catch (error:any) { - if (error.response && error.response.status === 401) { - // This is a 401 error; you can choose to handle it silently - } else { - // Handle other errors - } + +export const Login = () => { + const userStore = useUserStore(); + const navigate = useNavigate(); + useLayoutEffect(() => { + const check = async () => { + try { + const loggedin = await userStore.login(); + if (loggedin) navigate("/home"); + } catch (error: any) { + if (error.response && error.response.status === 401) { + // This is a 401 error; you can choose to handle it silently + } else { + // Handle other errors } - } - check() + } + }; + check(); // eslint-disable-next-line - },[]) - return ( - <> -
    -
    -
    -
    - Logo -
    - { - process.env.REACT_APP_AUTH_PATH && - -
    -
    - - - ); -} + }, []); + return ( + <> +
    +
    +
    +
    + Logo +
    + {process.env.REACT_APP_AUTH_PATH && ( + +
    +
    + + ); +}; diff --git a/frontend/code/src/Components/Play/assets/Watch.tsx b/frontend/code/src/Components/Play/assets/Watch.tsx index 0b9d626..15ff73f 100644 --- a/frontend/code/src/Components/Play/assets/Watch.tsx +++ b/frontend/code/src/Components/Play/assets/Watch.tsx @@ -1,21 +1,59 @@ export const Watch = () => { - return ( - - - - - - - - - - - - + return ( + + + + + + + + + + + + - - - - - ) -} \ No newline at end of file + + + ); +}; diff --git a/frontend/code/src/Components/Play/index.tsx b/frontend/code/src/Components/Play/index.tsx index 7211c46..0a4a76c 100644 --- a/frontend/code/src/Components/Play/index.tsx +++ b/frontend/code/src/Components/Play/index.tsx @@ -9,7 +9,6 @@ export const Play = () => { const [gameMode, setGameMode] = useState(""); const queueModalRef = useRef(null); const subscribeToGame = async () => { - // socketStore.socket?.emit try { socketStore.socket?.emit("startGame", { gameMode: "cassic" }); setGameMode("cassic"); @@ -25,7 +24,6 @@ export const Play = () => { } }; const subscribeToGameExtra = async () => { - // socketStore.socket?.emit try { socketStore.socket?.emit("startGame", { gameMode: "extra" }); setGameMode("extra"); diff --git a/frontend/code/src/Components/Profile/History.tsx b/frontend/code/src/Components/Profile/History.tsx index 5c39112..3a979e8 100644 --- a/frontend/code/src/Components/Profile/History.tsx +++ b/frontend/code/src/Components/Profile/History.tsx @@ -1,13 +1,12 @@ -import { Chart } from './assets/Chart' -import { Table } from './assets/Table' -export const History = (props:any) => { - return ( -
    -
    - Matches History - -
    - - - ) -} \ No newline at end of file +import { Chart } from "./assets/Chart"; +import { Table } from "./assets/Table"; +export const History = (props: any) => { + return ( +
    +
    + Matches History +
    +
    + + ); +}; diff --git a/frontend/code/src/Components/Profile/assets/Chart.tsx b/frontend/code/src/Components/Profile/assets/Chart.tsx index 404dcd2..e9a5cd2 100644 --- a/frontend/code/src/Components/Profile/assets/Chart.tsx +++ b/frontend/code/src/Components/Profile/assets/Chart.tsx @@ -1,9 +1,16 @@ export const Chart = () => { - return ( - - - - - - ) -} + return ( + + + + ); +}; diff --git a/frontend/code/src/Components/Profile/assets/Edit.tsx b/frontend/code/src/Components/Profile/assets/Edit.tsx index 8d206cc..9ec88f9 100644 --- a/frontend/code/src/Components/Profile/assets/Edit.tsx +++ b/frontend/code/src/Components/Profile/assets/Edit.tsx @@ -1,16 +1,35 @@ export const Edit = () => { - - return ( - - - - - - - + return ( + + + + + + + - - - - ) -} + + + ); +}; diff --git a/frontend/code/src/Components/Profile/assets/File.tsx b/frontend/code/src/Components/Profile/assets/File.tsx index ff07fa7..b2486db 100644 --- a/frontend/code/src/Components/Profile/assets/File.tsx +++ b/frontend/code/src/Components/Profile/assets/File.tsx @@ -1,11 +1,34 @@ export const File = () => { - return ( - - - - - - - - ) -} \ No newline at end of file + return ( + + + + + + + ); +}; diff --git a/frontend/code/src/Components/Profile/assets/MessageB.tsx b/frontend/code/src/Components/Profile/assets/MessageB.tsx index 04b910d..8df962e 100644 --- a/frontend/code/src/Components/Profile/assets/MessageB.tsx +++ b/frontend/code/src/Components/Profile/assets/MessageB.tsx @@ -1,22 +1,48 @@ -import { toast } from "react-hot-toast" -import api from "../../../Api/base" -export const Message = (props:any) => { - const handleSendReq = async() => { - toast.promise(api.post("friends/add",{friendId:props.profile.id}),{loading:`Sending friend request`,success:`request sent to ${props.profile.name.first}`,error:"could not send friend request"}) - } - - return ( - // - - - - - - - - - - - // - ) -} \ No newline at end of file +import { toast } from "react-hot-toast"; +import api from "../../../Api/base"; + +export const Message = (props: any) => { + const handleSendReq = async () => { + toast.promise(api.post("friends/add", { friendId: props.profile.id }), { + loading: `Sending friend request`, + success: `request sent to ${props.profile.name.first}`, + error: "could not send friend request", + }); + }; + + return ( + + + + + + + + + + + ); +}; diff --git a/frontend/code/src/Components/Profile/assets/Pong.tsx b/frontend/code/src/Components/Profile/assets/Pong.tsx index 25e3155..66c3337 100644 --- a/frontend/code/src/Components/Profile/assets/Pong.tsx +++ b/frontend/code/src/Components/Profile/assets/Pong.tsx @@ -1,13 +1,38 @@ -import './css/style.css' +import "./css/style.css"; export const Pong = () => { - return ( - - - - - - + return ( + + + + + + - ) -} + ); +}; diff --git a/frontend/code/src/Components/Profile/assets/ShareB.tsx b/frontend/code/src/Components/Profile/assets/ShareB.tsx index 54a76e4..bc64c5a 100644 --- a/frontend/code/src/Components/Profile/assets/ShareB.tsx +++ b/frontend/code/src/Components/Profile/assets/ShareB.tsx @@ -1,12 +1,25 @@ export const Share = () => { - return ( - - - - - - + return ( + + + + + - - ) -} \ No newline at end of file + ); +}; diff --git a/frontend/code/src/Components/Profile/assets/Table.tsx b/frontend/code/src/Components/Profile/assets/Table.tsx index 9a9a56b..a697528 100644 --- a/frontend/code/src/Components/Profile/assets/Table.tsx +++ b/frontend/code/src/Components/Profile/assets/Table.tsx @@ -8,7 +8,7 @@ import api from "../../../Api/base"; import toast from "react-hot-toast"; import { formatTime } from "../../Chat/Components/tools/utils"; import { useParams } from "react-router-dom"; -const getColor = (v1: any, v2: any , id:string ) => { +const getColor = (v1: any, v2: any, id: string) => { if (v1.score > v2.score && id === v1.id) return "text-lime-400"; if (v1.score < v2.score && id === v2.id) return "text-lime-400"; if (v1.score > v2.score && id !== v1.id) return "text-red-400"; @@ -16,34 +16,38 @@ const getColor = (v1: any, v2: any , id:string ) => { return "text-gray-400"; }; -const scoreHandler = (x:any, id:string) => { - if(x.match.Player1.score > x.match.Player2.score && x.match.Player1.id === id) - { - return " +1 " +const scoreHandler = (x: any, id: string) => { + if ( + x.match.Player1.score > x.match.Player2.score && + x.match.Player1.id === id + ) { + return " +1 "; + } else if ( + x.match.Player2.score > x.match.Player1.score && + x.match.Player2.id === id + ) { + return " +1 "; + } else if ( + x.match.Player1.score > x.match.Player2.score && + x.match.Player1.id !== id + ) { + return " -1 "; + } else if ( + x.match.Player2.score > x.match.Player1.score && + x.match.Player2.id !== id + ) { + return " -1 "; + } else { + return " 0 "; } - else if (x.match.Player2.score > x.match.Player1.score && x.match.Player2.id === id) - { - return " +1 " - } - else if(x.match.Player1.score > x.match.Player2.score && x.match.Player1.id !== id) - { - return " -1 " - } - else if (x.match.Player2.score > x.match.Player1.score && x.match.Player2.id !== id) - { - return " -1 " - } - else { - return " 0 " - } -} +}; export const Table = (props: any) => { const [history, setHistory] = useState([]); const [loading, setLoading] = useState(true); const [hasMore, setHasMore] = useState(true); const offset = useRef(0); - const {id} :any = useParams(); + const { id }: any = useParams(); const fetchData = async () => { try { const history: any = await api.get(`/game/history/${props.props.props}`, { @@ -155,11 +159,11 @@ export const Table = (props: any) => { className={`w-18 ${getColor( x.match.Player1, x.match.Player2, - id + id, )}`} > {" "} - {scoreHandler(x,id)} + {scoreHandler(x, id)} diff --git a/frontend/code/src/Components/Profile/index.tsx b/frontend/code/src/Components/Profile/index.tsx index 3d10f7b..dced71e 100644 --- a/frontend/code/src/Components/Profile/index.tsx +++ b/frontend/code/src/Components/Profile/index.tsx @@ -3,7 +3,7 @@ import { Pong } from "./assets/Pong"; import { History } from "./History"; import Hero from "./assets/Hero.gif"; import { useState, useEffect, useRef } from "react"; -import { Link, useNavigate, useParams, } from "react-router-dom"; +import { Link, useNavigate, useParams } from "react-router-dom"; import { Load } from "../Loading/"; import Newbie from "../Badges/Newbie.svg"; import Master from "../Badges/Master.svg"; @@ -74,7 +74,7 @@ export const Profile = () => { if (params.id !== user.id || params.id !== "me") fetchUser(); else setProfile(user); - //eslint-disable-next-line + // eslint-disable-next-line }, [params, user]); useEffect(() => { @@ -92,7 +92,7 @@ export const Profile = () => { } else { setOnlineStatus("offline"); } - } + }, ); }, [params.id, socketStore?.socket, user.id]); @@ -108,7 +108,6 @@ export const Profile = () => { success: `request sent to ${profile.name.first}`, error: "could not send friend request", }); - // setDisbaled("") }; const cancelRequest = async () => { setDisabled("btn-disabled"); @@ -196,8 +195,8 @@ export const Profile = () => { onlineStatus === "online" ? "text-green-500 border-green-500" : onlineStatus === "inGame" - ? "text-yellow-500 border-yellow-500" - : "text-red-500 border-red-500" + ? "text-yellow-500 border-yellow-500" + : "text-red-500 border-red-500", )} > {onlineStatus} @@ -211,37 +210,6 @@ export const Profile = () => {
    - {/* for debug */} - {/* */} {params.id !== "me" && params.id !== user.id && status === "none" && ( @@ -333,7 +301,7 @@ export const Profile = () => { "", "dm", undefined, - params.id + params.id, ).then((res) => { ChatState.setIsLoading(false); if (res?.status === 200 || res?.status === 201) { @@ -349,7 +317,7 @@ export const Profile = () => { navigate(`/Dm/${res?.data.id}`); } else { toast.error( - "You Can't Send Message To this User For Now, try Again later" + "You Can't Send Message To this User For Now, try Again later", ); } }); @@ -388,7 +356,7 @@ export const Profile = () => { } user.setGameWaitingId(data.gameId); inviteWaitingModalRef.current?.showModal(); - } + }, ); }} > @@ -414,7 +382,7 @@ export const Profile = () => { } user.setGameWaitingId(data.gameId); inviteWaitingModalRef.current?.showModal(); - } + }, ); }} > diff --git a/frontend/code/src/Components/Settings/assets/Edit.tsx b/frontend/code/src/Components/Settings/assets/Edit.tsx index 721515a..c15ae6a 100644 --- a/frontend/code/src/Components/Settings/assets/Edit.tsx +++ b/frontend/code/src/Components/Settings/assets/Edit.tsx @@ -1,11 +1,24 @@ export const Edit = () => { - return ( - - - - - - - - ) -} \ No newline at end of file + return ( + + + + + + + ); +}; diff --git a/frontend/code/src/Components/Settings/assets/Inputs.tsx b/frontend/code/src/Components/Settings/assets/Inputs.tsx index 962695a..59374ff 100644 --- a/frontend/code/src/Components/Settings/assets/Inputs.tsx +++ b/frontend/code/src/Components/Settings/assets/Inputs.tsx @@ -45,37 +45,39 @@ export const Inputs = (props: InputsProps) => { { className: "font-poppins font-bold relative top-[6vh] bg-base-100 text-white", - } + }, ); // Update field locally after a successful request - toastPromise.then(() => { - switch (props.name) { - case "First name": - user.updateFirstName(data[`${props.payload}`]); - break; - case "Last name": - user.updateLastName(data[`${props.payload}`]); - break; - case "Email": - user.updateEmail(data[`${props.payload}`]); - break; - case "Phone": - user.updatePhone(data[`${props.payload}`]); - break; - case "Bio": - user.updateBio(data[`${props.payload}`]); - break; - case "Username": - user.updateUsername(data[`${props.payload}`]); - break; - } - }).catch((error) => { - if ((error as any)?.response.data.message) { - toast.error((error as any)?.response.data.message); - } else { - toast.error('Invalid field'); - } - }) + toastPromise + .then(() => { + switch (props.name) { + case "First name": + user.updateFirstName(data[`${props.payload}`]); + break; + case "Last name": + user.updateLastName(data[`${props.payload}`]); + break; + case "Email": + user.updateEmail(data[`${props.payload}`]); + break; + case "Phone": + user.updatePhone(data[`${props.payload}`]); + break; + case "Bio": + user.updateBio(data[`${props.payload}`]); + break; + case "Username": + user.updateUsername(data[`${props.payload}`]); + break; + } + }) + .catch((error) => { + if ((error as any)?.response.data.message) { + toast.error((error as any)?.response.data.message); + } else { + toast.error("Invalid field"); + } + }); }; const handleError = useCallback((errors: FieldErrors) => { @@ -122,7 +124,7 @@ export const Inputs = (props: InputsProps) => {
    @@ -131,7 +133,7 @@ export const Inputs = (props: InputsProps) => { type="email" className={classNames( "h-12 w-full rounded-3xl text-center", - props.className + props.className, )} defaultValue={props.data} placeholder={props.payload} @@ -151,7 +153,7 @@ export const Inputs = (props: InputsProps) => { type="text" className={classNames( "h-12 w-full rounded-3xl text-center", - props.className + props.className, )} defaultValue={props.data} placeholder={props.payload} diff --git a/frontend/code/src/Components/Settings/index.tsx b/frontend/code/src/Components/Settings/index.tsx index 5432691..e821498 100644 --- a/frontend/code/src/Components/Settings/index.tsx +++ b/frontend/code/src/Components/Settings/index.tsx @@ -17,7 +17,7 @@ import googleAuthenticatorIcon from "../images/google-authenticator.svg"; export const Setting = () => { const TOTPSecretKey = useMemo( () => btoa(Math.random().toString(36)).substring(0, 16), - [] + [], ); const [TOTPCode, setTOTPCode] = useState(""); @@ -30,8 +30,20 @@ export const Setting = () => { const user = useUserStore(); const [myuser, setMyuser] = useState(user); const data_names = ["First name", "Last name", "Email", "Username", "Bio"]; - const payload_objects = ["firstName", "lastName", "email", "Username", "discreption"]; - const data_content = [user.name.first, user.name.last, user.email, user.username, user.bio]; + const payload_objects = [ + "firstName", + "lastName", + "email", + "Username", + "discreption", + ]; + const data_content = [ + user.name.first, + user.name.last, + user.email, + user.username, + user.bio, + ]; useEffect(() => { setMyuser(user); @@ -70,17 +82,29 @@ export const Setting = () => { }} >
    = 0 ? "":"opacity-30"}`} + className={`h-[9vh] md:h-[12vh] xl:h-[14vh] ${ + myuser?.achievement !== null && myuser?.achievement >= 0 + ? "" + : "opacity-30" + }`} src={Newbie} alt="newbie badge" /> = 1 ? "":"opacity-30"}`} + className={`h-[9vh] md:h-[12vh] xl:h-[14vh] ${ + myuser?.achievement !== null && myuser?.achievement >= 1 + ? "" + : "opacity-30" + }`} src={Master} alt="Master badge" /> = 2 ? "":"opacity-30"}`} + className={`h-[9vh] md:h-[12vh] xl:h-[14vh] ${ + myuser?.achievement !== null && myuser?.achievement >= 2 + ? "" + : "opacity-30" + }`} src={Ultimate} alt="Ultimate badge" /> @@ -134,7 +158,7 @@ export const Setting = () => { no
    @@ -189,7 +213,7 @@ export const Setting = () => { otp: TOTPCode, secret: TOTPSecretKey, action: "enable", - } + }, ); user.toggleTfa(); toast.success(response.data.message); @@ -247,7 +271,7 @@ export const Setting = () => { { otp: TOTPCode, action: "disable", - } + }, ); user.toggleTfa(); toast.success(response.data.message); diff --git a/frontend/code/src/Components/Validate2Fa/index.tsx b/frontend/code/src/Components/Validate2Fa/index.tsx index b02fa76..c4f4ce5 100644 --- a/frontend/code/src/Components/Validate2Fa/index.tsx +++ b/frontend/code/src/Components/Validate2Fa/index.tsx @@ -20,8 +20,9 @@ export const Validate2Fa = () => { }) .catch(() => {}); - //eslint-disable-next-line + // eslint-disable-next-line }, []); + return (
    { return await dataLoader()}, it was expermintal it's good for multi compononet fetching but not good for only one because in case of multi fetch it launches fetch paraller and not waiting each compononet to laod lazy: async () => { let { Home } = await import("../Components/Home"); return { Component: Home }; @@ -37,7 +36,7 @@ const router = createBrowserRouter([ return { Component: Setting }; }, }, - + { path: "Profile/:id", lazy: async () => { @@ -55,17 +54,19 @@ const router = createBrowserRouter([ { path: "Dm/:id", lazy: async () => { - let { UserToUserChat } = await import("../Components/Chat/Components/UserToUserChat"); + let { UserToUserChat } = await import( + "../Components/Chat/Components/UserToUserChat" + ); return { Component: UserToUserChat }; }, }, { path: "Game/:id", lazy: async () => { - let { Game } = await import("../Components/Game") - return { Component: Game}; + let { Game } = await import("../Components/Game"); + return { Component: Game }; }, - } + }, ], }, { diff --git a/frontend/code/src/Stores/stores.ts b/frontend/code/src/Stores/stores.ts index 348f23e..7d39696 100644 --- a/frontend/code/src/Stores/stores.ts +++ b/frontend/code/src/Stores/stores.ts @@ -175,13 +175,14 @@ export const useUserStore = createWithEqualityFn()( }, updatePhone: (phone: State["phone"]) => set(() => ({ phone: phone })), updateBio: (bio: State["bio"]) => set(() => ({ bio: bio })), - updateUsername: (username: State["username"]) => set(() => ({ username: username })), + updateUsername: (username: State["username"]) => + set(() => ({ username: username })), setAvatar: (picture: State["picture"]) => set(() => ({ picture: picture })), login: async () => { const res = await api.get("/profile/me"); var user_data = res.data; - // user_data.picture= null + const check = user_data.picture.large.split`/`; if (check[check.length - 1] === "null") user_data.picture = null; const userInitialValue: State = { diff --git a/frontend/code/src/index.tsx b/frontend/code/src/index.tsx index eb82f23..6f37e59 100644 --- a/frontend/code/src/index.tsx +++ b/frontend/code/src/index.tsx @@ -5,7 +5,7 @@ import { Toaster } from "react-hot-toast"; import { AllRouters } from "./Routes"; const root = ReactDOM.createRoot( - document.getElementById("root") as HTMLElement + document.getElementById("root") as HTMLElement, ); root.render( @@ -23,7 +23,7 @@ root.render( }} /> - + , ); reportWebVitals(); diff --git a/frontend/code/src/reportWebVitals.ts b/frontend/code/src/reportWebVitals.ts index 49a2a16..5fa3583 100644 --- a/frontend/code/src/reportWebVitals.ts +++ b/frontend/code/src/reportWebVitals.ts @@ -1,8 +1,8 @@ -import { ReportHandler } from 'web-vitals'; +import { ReportHandler } from "web-vitals"; const reportWebVitals = (onPerfEntry?: ReportHandler) => { if (onPerfEntry && onPerfEntry instanceof Function) { - import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { getCLS(onPerfEntry); getFID(onPerfEntry); getFCP(onPerfEntry); diff --git a/frontend/code/src/setupTests.ts b/frontend/code/src/setupTests.ts index 8f2609b..1dd407a 100644 --- a/frontend/code/src/setupTests.ts +++ b/frontend/code/src/setupTests.ts @@ -2,4 +2,4 @@ // allows you to do things like: // expect(element).toHaveTextContent(/react/i) // learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom'; +import "@testing-library/jest-dom"; diff --git a/frontend/code/tailwind.config.js b/frontend/code/tailwind.config.js index 2d033ba..84375cd 100644 --- a/frontend/code/tailwind.config.js +++ b/frontend/code/tailwind.config.js @@ -4,42 +4,35 @@ module.exports = { "./src/**/*.{js,jsx,ts,tsx}", "./src/**/**/*.{js,jsx,ts,tsx}", "./src/**/**/**/*.{js,jsx,ts,tsx}", - ], theme: { extend: { animation: { - border: 'background ease infinite', + border: "background ease infinite", }, keyframes: { background: { - '0%, 100%': { backgroundPosition: '0% 50%' }, - '50%': { backgroundPosition: '100% 50%' }, + "0%, 100%": { backgroundPosition: "0% 50%" }, + "50%": { backgroundPosition: "100% 50%" }, }, }, screens: { - '3xl': '1700px', + "3xl": "1700px", }, fontFamily: { - poppins: ['Poppins', 'sans-serif'], - lexend: ['Lexend Peta', 'sans-serif'], - montserrat: ['Montserrat', 'sans-serif'] - + poppins: ["Poppins", "sans-serif"], + lexend: ["Lexend Peta", "sans-serif"], + montserrat: ["Montserrat", "sans-serif"], }, backgroundImage: { - 'login': "url('./Components/Login/Assets/bg.gif')", - 'gif-error': "url('./Components/Error/Assets/Error.gif')", - + login: "url('./Components/Login/Assets/bg.gif')", + "gif-error": "url('./Components/Error/Assets/Error.gif')", }, - }, }, - plugins: [ - require("daisyui"), - require('preline/plugin'), - ], + plugins: [require("daisyui"), require("preline/plugin")], daisyui: { themes: [ { @@ -48,48 +41,45 @@ module.exports = { "base-200": "#272932", - "primary": "#7940CF", + primary: "#7940CF", "primary-content": "#5921CB", - "secondary": "#6A4CFC", + secondary: "#6A4CFC", "secondary-content": "#1A1C26", - "accent": "#1A1C26", + accent: "#1A1C26", - "neutral": "#FFFFFF", + neutral: "#FFFFFF", - "info": "#3e9cea", + info: "#3e9cea", - "success": "#1ba177", + success: "#1ba177", - "warning": "#99670f", + warning: "#99670f", - "error": "#e93f6f", + error: "#e93f6f", }, secondtheme: { - - "base-100": "#2b2d50", "base-200": "#1d252f", - "primary": "#fcecb3", + primary: "#fcecb3", "primary-content": "#be8f04", - "secondary": "#4c95c9", + secondary: "#4c95c9", "secondary-content": "#79f289", - "accent": "#66ebd9", + accent: "#66ebd9", - "neutral": "#FFFFFF", + neutral: "#FFFFFF", - "error": "#e93535", + error: "#e93535", }, - }, "light", "dark", @@ -103,6 +93,6 @@ module.exports = { prefix: "", // prefix for daisyUI classnames (components, modifiers and responsive class names. Not colors) tailwindcss: {}, autoprefixer: {}, - cssnano: {} + cssnano: {}, }, -} \ No newline at end of file +}; From 343629ee5274a5e5047634094fdbb7039d34ecbb Mon Sep 17 00:00:00 2001 From: ismail Date: Thu, 16 Nov 2023 17:03:38 +0100 Subject: [PATCH 3/3] Fixed production build --- backend/code/accountPickerCli.ts | 74 ------ backend/code/package.json | 4 +- backend/code/seeder.ts | 162 ------------ .../src/auth/utils/jwt_utils/jwt_utils.ts | 2 +- backend/code/src/game/game.ts | 16 +- backend/code/src/gateways/gateways.gateway.ts | 2 +- backend/code/src/main.ts | 7 +- backend/code/src/profile/profile.service.ts | 8 +- docker-compose.yaml | 27 +- frontend/code/README.md | 2 +- frontend/code/package-lock.json | 242 ------------------ frontend/code/package.json | 10 +- .../Chat/Components/RoomChatHelpers.tsx | 14 +- .../Components/Chat/Services/ChatServices.ts | 2 +- .../Chat/Services/SocketsServices.ts | 19 +- .../Components/FirstLogin/UploadAvatar.tsx | 2 + frontend/code/src/Components/Layout/index.tsx | 11 + .../code/src/Components/Play/assets/Watch.tsx | 59 ----- frontend/code/src/Components/Play/index.tsx | 23 +- .../code/src/Components/Settings/index.tsx | 8 +- frontend/code/src/setupTests.ts | 5 - nginx/default.conf | 66 ++--- 22 files changed, 118 insertions(+), 647 deletions(-) delete mode 100644 backend/code/accountPickerCli.ts delete mode 100644 backend/code/seeder.ts delete mode 100644 frontend/code/src/Components/Play/assets/Watch.tsx delete mode 100644 frontend/code/src/setupTests.ts diff --git a/backend/code/accountPickerCli.ts b/backend/code/accountPickerCli.ts deleted file mode 100644 index 9cb9e72..0000000 --- a/backend/code/accountPickerCli.ts +++ /dev/null @@ -1,74 +0,0 @@ -import * as figlet from 'figlet'; -import * as fs from 'fs'; -import * as readline from 'node:readline'; -(async () => { - const header = figlet.textSync('Account Picker', { - font: 'Roman', - horizontalLayout: 'default', - verticalLayout: 'default', - }); - - console.log(header); - - const users = fs - .readFileSync('./users.txt', 'utf8') - .trim() - .split('\n') - .map((user) => { - const [email, password] = user.split(':'); - return { email, password }; - }); - - // list users to choose from - const userChoices = users.map((user, index) => { - return { - name: `${user.email} (${user.password})`, - value: index, - }; - }); - - // list uset userChoices - // - for (const userChoice of userChoices) { - console.log(`${userChoice.value}: ${userChoice.name}`); - } - - const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, - }); - - const question = (query: string) => - new Promise((resolve) => - rl.question(query, (ans) => { - resolve(ans); - }), - ); - - const userIndex = await question('User index: '); - const user = users[parseInt(userIndex as string, 10)]; - console.log(`You chose: ${user.email} (${user.password})`); - rl.close(); - - const codeTemplate = ` -var myHeaders = new Headers(); -myHeaders.append("Content-Type", "application/json"); - -var raw = JSON.stringify({ - "email": "${user.email}", - "password": "${user.password}" -}); - -var requestOptions = { - method: 'POST', - headers: myHeaders, - body: raw, - redirect: 'follow' -}; - -fetch("http://test.reversablecode.com:3001/auth/login", requestOptions) - .then(response => response.text()) - .then(result => console.log(result)) - .catch(error => console.log('error', error));`; - console.log(codeTemplate); -})(); diff --git a/backend/code/package.json b/backend/code/package.json index c396818..a3c214d 100644 --- a/backend/code/package.json +++ b/backend/code/package.json @@ -10,12 +10,12 @@ "private": true, "license": "UNLICENSED", "scripts": { - "build": "nest build", + "build": "npm run db:generate && nest build", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "start": "nest start", "start:dev": "npm run db:generate && nest start --watch", "start:debug": "nest start --debug --watch", - "start:prod": "node dist/src/main", + "start:prod": "node dist/main", "db:generate": "prisma generate", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "jest", diff --git a/backend/code/seeder.ts b/backend/code/seeder.ts deleted file mode 100644 index 40bb400..0000000 --- a/backend/code/seeder.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { PrismaClient, User } from '@prisma/client'; -import { faker } from '@faker-js/faker'; -import * as bcrypt from 'bcrypt'; -import * as fs from 'fs'; - -class dataSeeder extends PrismaClient { - constructor() { - super({ - datasources: { - db: { - url: process.env.DATABASE_URL, - }, - }, - }); - } - - async seed() { - await this.$connect(); - const users = faker.helpers.multiple(this.createRandomUser, { count: 10 }); - const registeredUsers = await this.registerUser(users); - await this.makeFriendship(registeredUsers); - await this.makeMatch(registeredUsers); - await this.createRoom(registeredUsers); - await this.$disconnect(); - } - - private async registerUser(users: any): Promise { - if (fs.existsSync('users.txt')) { - console.log('users.txt exists'); - fs.unlinkSync('users.txt'); - } - const new_users: User[] = []; - for await (const user of users) { - fs.appendFile('users.txt', `${user.email}:${user.password}\n`, (err) => { - if (err) throw err; - }); - - const hash = await bcrypt.hash(user.password, 10); - - const new_user = await this.user.create({ - data: { - email: user.email, - password: hash, - Username: user.username, - firstName: user.firstName, - lastName: user.lastName, - avatar: user.avatar, - discreption: user.bio, - profileFinished: true, - }, - }); - new_users.push(new_user); - } - return new_users; - } - - private async makeFriendship(users: User[]) { - for await (const user of users) { - const randomUser = users[Math.floor(Math.random() * users.length)]; - if (randomUser.userId !== user.userId) { - const friendshipid = [user.userId, randomUser.userId].sort().join('-'); - await this.friend.upsert({ - where: { - id: friendshipid, - }, - create: { - id: friendshipid, - from: { - connect: { - userId: user.userId, - }, - }, - to: { - connect: { - userId: randomUser.userId, - }, - }, - accepted: true, - }, - update: {}, - }); - } - } - } - - private async makeMatch(users: User[]) { - for await (const user of users) { - const randomUser = users[Math.floor(Math.random() * users.length)]; - if (randomUser.userId !== user.userId) { - await this.match.create({ - data: { - participant1Id: user.userId, - participant2Id: randomUser.userId, - winner_id: Math.random() > 0.5 ? user.userId : randomUser.userId, - score1: Math.floor(Math.random() * 10), - score2: Math.floor(Math.random() * 10), - }, - }); - } - } - } - - private createRandomUser() { - return { - username: faker.internet.userName(), - email: faker.internet.email(), - avatar: 'v1698656518/nest-blog/clocnzgx80006q73seyj9hzx5.png', - password: faker.internet.password(), - firstName: faker.person.firstName(), - lastName: faker.person.lastName(), - bio: faker.person.bio(), - }; - } - - private async createRoom(users: User[]) { - const owner = users[Math.floor(Math.random() * users.length)]; - const roomData = { - name: faker.lorem.word(), - ownerId: owner.userId, - }; - - // add random users to the room - const filtredUsers = users.filter((user) => user.userId !== owner.userId); - const randomUsers = filtredUsers.slice( - 0, - Math.floor(Math.random() * filtredUsers.length), - ); - - const room = await this.room.create({ - data: { - name: roomData.name, - ownerId: roomData.ownerId, - type: 'public', - }, - }); - - for await (const user of randomUsers) { - await this.roomMember.create({ - data: { - userId: user.userId, - roomId: room.id, - is_admin: Math.random() > 0.8 ? true : false, - }, - }); - } - await this.roomMember.create({ - data: { - userId: owner.userId, - roomId: room.id, - is_admin: true, - }, - }); - - console.log('roomid: ', room.id); - console.log('ownerid: ', owner.userId); - console.log('randomUsers: ', randomUsers); - } -} - -(async () => { - await new dataSeeder().seed(); -})(); diff --git a/backend/code/src/auth/utils/jwt_utils/jwt_utils.ts b/backend/code/src/auth/utils/jwt_utils/jwt_utils.ts index 596d6b6..2ac1115 100644 --- a/backend/code/src/auth/utils/jwt_utils/jwt_utils.ts +++ b/backend/code/src/auth/utils/jwt_utils/jwt_utils.ts @@ -17,7 +17,7 @@ export class JwtUtils { { username, sub: userId }, { secret: JwtConsts.at_secret, - expiresIn: '15m', + expiresIn: '2h', }, ), this.jwtService.signAsync( diff --git a/backend/code/src/game/game.ts b/backend/code/src/game/game.ts index 7ec39e8..12e8637 100644 --- a/backend/code/src/game/game.ts +++ b/backend/code/src/game/game.ts @@ -283,26 +283,26 @@ export class Game { } private checkForWinner() { if (this.p1Score >= 5) { - this.p1socket.emit('win', 'you win'); - this.p2socket.emit('lose', 'you lose'); + this.p1socket.emit('win', 'you won'); + this.p2socket.emit('lose', 'you lost'); this.emitGameEnd('end'); } if (this.p2Score >= 5) { - this.p2socket.emit('win', 'you win'); - this.p1socket.emit('lose', 'you lose'); + this.p2socket.emit('win', 'you won'); + this.p1socket.emit('lose', 'you lost'); this.emitGameEnd('end'); } } private handleP1Disconnect = () => { - this.p2socket.emit('win', 'you win other player leave the game'); - this.p1socket.emit('lose', 'you win other player leave the game'); + this.p2socket.emit('win', 'you won, the other player left the game'); + this.p1socket.emit('lose', 'you lost'); this.emitGameEnd('p1Leave'); }; private handleP2Disconnect = () => { - this.p1socket.emit('win', 'you win other player leave the game'); - this.p2socket.emit('lose', 'you lost other player leave the game'); + this.p1socket.emit('win', 'you won, the other player left the game'); + this.p2socket.emit('lose', 'you lost'); this.emitGameEnd('p2Leave'); }; diff --git a/backend/code/src/gateways/gateways.gateway.ts b/backend/code/src/gateways/gateways.gateway.ts index dbe7015..7be7aa1 100644 --- a/backend/code/src/gateways/gateways.gateway.ts +++ b/backend/code/src/gateways/gateways.gateway.ts @@ -26,7 +26,7 @@ interface GameInvite { @WebSocketGateway(3004, { cors: { - origin: ['http://test.reversablecode.com:3001'], + origin: process.env.WS_CORS_ORIGIN?.split(',') || ['http://localhost:3001'], }, transports: ['websocket'], }) diff --git a/backend/code/src/main.ts b/backend/code/src/main.ts index 673be89..b7726c6 100644 --- a/backend/code/src/main.ts +++ b/backend/code/src/main.ts @@ -14,10 +14,9 @@ import { GatewayAdapter } from './gateways/gateway-adapter'; async function bootstrap() { const app = await NestFactory.create(AppModule); const corsOptions = { - origin: [ - 'http://test.reversablecode.com:9000', - 'http://test.reversablecode.com:8000', - 'http://test.reversablecode.com:3000', + origin: process.env.CORS_ORIGIN?.split(',') || [ + 'http://localhost:8000', + 'http://localhost:3000', 'http://142.93.161.63', 'http://164.92.243.105', ], diff --git a/backend/code/src/profile/profile.service.ts b/backend/code/src/profile/profile.service.ts index 716332d..d97f361 100644 --- a/backend/code/src/profile/profile.service.ts +++ b/backend/code/src/profile/profile.service.ts @@ -28,8 +28,8 @@ export class ProfileService { wonMatches === 0 ? null : wonMatches >= 100 - ? 2 - : Math.floor(Math.log10(wonMatches)); + ? 2 + : Math.floor(Math.log10(wonMatches)); return new ProfileDto({ ...user, achievement }, false); } @@ -58,8 +58,8 @@ export class ProfileService { wonMatches === 0 ? null : wonMatches >= 100 - ? 2 - : Math.floor(Math.log10(wonMatches)); + ? 2 + : Math.floor(Math.log10(wonMatches)); return new ProfileDto({ ...user, achievement }, true); } diff --git a/docker-compose.yaml b/docker-compose.yaml index a7be7d1..3e59164 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -10,18 +10,6 @@ services : networks: - pongnet init: true - restart: always - - database: - image: postgres - restart: always - environment: - POSTGRES_PASSWORD: test - volumes: - - database:/var/lib/postgresql/data - networks: - - pongnet - restart: always backend: build: @@ -32,7 +20,6 @@ services : - pongnet depends_on: - database - restart: always ports: - 3001:3001 - 3004:3004 @@ -55,15 +42,27 @@ services : init: true restart: always + database: + image: postgres + restart: always + env_file: + - ./.env + volumes: + - database:/var/lib/postgresql/data + networks: + - pongnet + migration: build: context: ./backend/code/prisma dockerfile: Dockerfile image: prisma_migration:local + env_file: + - ./.env networks: - pongnet depends_on: - - backend + - database volumes: front: diff --git a/frontend/code/README.md b/frontend/code/README.md index 104e61d..b87cb00 100644 --- a/frontend/code/README.md +++ b/frontend/code/README.md @@ -9,7 +9,7 @@ In the project directory, you can run: ### `npm start` Runs the app in the development mode.\ -Open [http://test.reversablecode.com:3000](http://test.reversablecode.com:3000) to view it in the browser. +Open [http://localhost:3000](http://localhost:3000) to view it in the browser. The page will reload if you make edits.\ You will also see any lint errors in the console. diff --git a/frontend/code/package-lock.json b/frontend/code/package-lock.json index 9471470..72affdb 100644 --- a/frontend/code/package-lock.json +++ b/frontend/code/package-lock.json @@ -9,15 +9,10 @@ "version": "0.1.0", "dependencies": { "@react-spring/web": "^9.7.3", - "@testing-library/jest-dom": "^5.17.0", - "@testing-library/react": "^13.4.0", - "@testing-library/user-event": "^13.5.0", - "@types/jest": "^27.5.2", "@types/node": "^16.18.38", "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "axios": "^1.6.0", - "framer-motion": "^10.16.4", "preline": "^1.9.0", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -29,7 +24,6 @@ "react-konva": "^18.2.10", "react-qr-code": "^2.0.12", "react-scripts": "^5.0.1", - "react-virtuoso": "^4.6.2", "socket.io-client": "^4.7.2", "tailwind-merge": "^2.0.0", "typescript": "^4.9.5", @@ -50,11 +44,6 @@ "node": ">=0.10.0" } }, - "node_modules/@adobe/css-tools": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.1.tgz", - "integrity": "sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==" - }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", @@ -3456,108 +3445,6 @@ "url": "https://github.com/sponsors/gregberge" } }, - "node_modules/@testing-library/dom": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz", - "integrity": "sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.1.3", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@testing-library/jest-dom": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", - "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", - "dependencies": { - "@adobe/css-tools": "^4.0.1", - "@babel/runtime": "^7.9.2", - "@types/testing-library__jest-dom": "^5.9.1", - "aria-query": "^5.0.0", - "chalk": "^3.0.0", - "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.5.6", - "lodash": "^4.17.15", - "redent": "^3.0.0" - }, - "engines": { - "node": ">=8", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/react": { - "version": "13.4.0", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz", - "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^8.5.0", - "@types/react-dom": "^18.0.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@testing-library/react/node_modules/@testing-library/dom": { - "version": "8.20.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", - "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.1.3", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@testing-library/user-event": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", - "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", - "dependencies": { - "@babel/runtime": "^7.12.5" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - }, - "peerDependencies": { - "@testing-library/dom": ">=7.21.4" - } - }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -3574,11 +3461,6 @@ "node": ">=10.13.0" } }, - "node_modules/@types/aria-query": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz", - "integrity": "sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==" - }, "node_modules/@types/babel__core": { "version": "7.20.1", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", @@ -3742,15 +3624,6 @@ "@types/istanbul-lib-report": "*" } }, - "node_modules/@types/jest": { - "version": "27.5.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", - "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", - "dependencies": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, "node_modules/@types/json-schema": { "version": "7.0.12", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", @@ -3890,14 +3763,6 @@ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, - "node_modules/@types/testing-library__jest-dom": { - "version": "5.14.9", - "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", - "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", - "dependencies": { - "@types/jest": "*" - } - }, "node_modules/@types/trusted-types": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", @@ -5979,11 +5844,6 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" - }, "node_modules/cssdb": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.7.2.tgz", @@ -6415,11 +6275,6 @@ "node": ">=6.0.0" } }, - "node_modules/dom-accessibility-api": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==" - }, "node_modules/dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -7937,44 +7792,6 @@ "url": "https://github.com/sponsors/rawify" } }, - "node_modules/framer-motion": { - "version": "10.16.4", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.16.4.tgz", - "integrity": "sha512-p9V9nGomS3m6/CALXqv6nFGMuFOxbWsmaOrdmhyQimMIlLl3LC7h7l86wge/Js/8cRu5ktutS/zlzgR7eBOtFA==", - "dependencies": { - "tslib": "^2.4.0" - }, - "optionalDependencies": { - "@emotion/is-prop-valid": "^0.8.2" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/framer-motion/node_modules/@emotion/is-prop-valid": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", - "optional": true, - "dependencies": { - "@emotion/memoize": "0.7.4" - } - }, - "node_modules/framer-motion/node_modules/@emotion/memoize": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", - "optional": true - }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -8704,14 +8521,6 @@ "node": ">=0.8.19" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -10543,14 +10352,6 @@ "yallist": "^3.0.2" } }, - "node_modules/lz-string": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", - "bin": { - "lz-string": "bin/bin.js" - } - }, "node_modules/magic-string": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", @@ -10689,14 +10490,6 @@ "node": ">=6" } }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "engines": { - "node": ">=4" - } - }, "node_modules/mini-css-extract-plugin": { "version": "2.7.6", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", @@ -13241,18 +13034,6 @@ } } }, - "node_modules/react-virtuoso": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.6.2.tgz", - "integrity": "sha512-vvlqvzPif+MvBrJ09+hJJrVY0xJK9yran+A+/1iwY78k0YCVKsyoNPqoLxOxzYPggspNBNXqUXEcvckN29OxyQ==", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": ">=16 || >=17 || >= 18", - "react-dom": ">=16 || >=17 || >= 18" - } - }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -13296,18 +13077,6 @@ "node": ">=6.0.0" } }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/reflect.getprototypeof": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", @@ -14460,17 +14229,6 @@ "node": ">=6" } }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", diff --git a/frontend/code/package.json b/frontend/code/package.json index a50d317..6c6f8e0 100644 --- a/frontend/code/package.json +++ b/frontend/code/package.json @@ -4,15 +4,10 @@ "private": true, "dependencies": { "@react-spring/web": "^9.7.3", - "@testing-library/jest-dom": "^5.17.0", - "@testing-library/react": "^13.4.0", - "@testing-library/user-event": "^13.5.0", - "@types/jest": "^27.5.2", "@types/node": "^16.18.38", "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "axios": "^1.6.0", - "framer-motion": "^10.16.4", "preline": "^1.9.0", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -24,7 +19,6 @@ "react-konva": "^18.2.10", "react-qr-code": "^2.0.12", "react-scripts": "^5.0.1", - "react-virtuoso": "^4.6.2", "socket.io-client": "^4.7.2", "tailwind-merge": "^2.0.0", "typescript": "^4.9.5", @@ -34,13 +28,11 @@ "scripts": { "start": "FORK_TS_CHECKER=false react-scripts start", "build": "FORK_TS_CHECKER=false react-scripts build", - "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": [ - "react-app", - "react-app/jest" + "react-app" ], "rules": { "jsx-a11y/anchor-is-valid": "off" diff --git a/frontend/code/src/Components/Chat/Components/RoomChatHelpers.tsx b/frontend/code/src/Components/Chat/Components/RoomChatHelpers.tsx index 448da3d..64e7d51 100644 --- a/frontend/code/src/Components/Chat/Components/RoomChatHelpers.tsx +++ b/frontend/code/src/Components/Chat/Components/RoomChatHelpers.tsx @@ -248,7 +248,7 @@ export const CreateNewRoomModal = () => { selectedOption === RoomType.protected ? RoomPassword : undefined, ).then((res) => { if (res?.status !== 200 && res?.status !== 201) { - toast.error("something went wrong, try again"); + toast.error(res?.data?.message || "something went wrong, try again"); resetModalState(); } else { toast.success("Room Created Successfully"); @@ -580,11 +580,13 @@ export const FriendStatusTile = (props: { user: RoomMember }) => {
    - + + +

    diff --git a/frontend/code/src/Components/Chat/Services/ChatServices.ts b/frontend/code/src/Components/Chat/Services/ChatServices.ts index df07d87..14ae68d 100644 --- a/frontend/code/src/Components/Chat/Services/ChatServices.ts +++ b/frontend/code/src/Components/Chat/Services/ChatServices.ts @@ -16,7 +16,7 @@ export const createNewRoomCall = async ( }); return response; } catch (e: any) { - // Do nothing + return e?.response; } }; diff --git a/frontend/code/src/Components/Chat/Services/SocketsServices.ts b/frontend/code/src/Components/Chat/Services/SocketsServices.ts index f33b6f9..312434c 100644 --- a/frontend/code/src/Components/Chat/Services/SocketsServices.ts +++ b/frontend/code/src/Components/Chat/Services/SocketsServices.ts @@ -8,7 +8,7 @@ interface SocketStore { setSocket: () => any; } -export const useSocketStore = create((set, get) => ({ +export const useSocketStore = create((set) => ({ socket: null, connected: false, setSocket: () => { @@ -16,13 +16,16 @@ export const useSocketStore = create((set, get) => ({ set((state) => { if (state.socket === null) { - newSocket = io("http://test.reversablecode.com:3004", { - transports: ["websocket"], - reconnection: true, - reconnectionDelay: 1000, - reconnectionDelayMax: 1000, - reconnectionAttempts: 5, - }); + newSocket = io( + process.env.REACT_APP_SOCKET_ENDPOINT || "http://localhost:3004", + { + transports: ["websocket"], + reconnection: true, + reconnectionDelay: 1000, + reconnectionDelayMax: 1000, + reconnectionAttempts: 5, + }, + ); // Set socket set({ ...state, socket: newSocket }); diff --git a/frontend/code/src/Components/FirstLogin/UploadAvatar.tsx b/frontend/code/src/Components/FirstLogin/UploadAvatar.tsx index cf86ebc..7aa5813 100644 --- a/frontend/code/src/Components/FirstLogin/UploadAvatar.tsx +++ b/frontend/code/src/Components/FirstLogin/UploadAvatar.tsx @@ -57,6 +57,8 @@ export const UploadAvatar = () => { toast.error(`${data_names[index]} ${ERROR_MESSAGES[1]} 4`); if (errors[`${item}`]?.type === "maxLength") toast.error(`${data_names[index]} ${ERROR_MESSAGES[2]} 50 `); + if (errors[`${item}`]?.type === "pattern") + toast.error(`${errors[`${item}`]?.message}`); }); }; diff --git a/frontend/code/src/Components/Layout/index.tsx b/frontend/code/src/Components/Layout/index.tsx index b2a6e51..eef3cc6 100644 --- a/frontend/code/src/Components/Layout/index.tsx +++ b/frontend/code/src/Components/Layout/index.tsx @@ -69,6 +69,16 @@ export const Layout: FC = (): JSX.Element => { // eslint-disable-next-line }, [path]); useLayoutEffect(() => { + // Prevent ESC key + const preventEsc = (e: KeyboardEvent) => { + if (e.key === "Escape") { + e.preventDefault(); + e.stopPropagation(); + return false; + } + }; + document.addEventListener("keydown", preventEsc, false); + const log = async () => { try { await user.login(); @@ -91,6 +101,7 @@ export const Layout: FC = (): JSX.Element => { invitationGameRef.current?.showModal(); }); return () => { + document.removeEventListener("keydown", preventEsc, false); socketStore.socket?.off("invitedToGame"); }; // eslint-disable-next-line diff --git a/frontend/code/src/Components/Play/assets/Watch.tsx b/frontend/code/src/Components/Play/assets/Watch.tsx deleted file mode 100644 index 15ff73f..0000000 --- a/frontend/code/src/Components/Play/assets/Watch.tsx +++ /dev/null @@ -1,59 +0,0 @@ -export const Watch = () => { - return ( - - - - - - - - - - - - - - - - ); -}; diff --git a/frontend/code/src/Components/Play/index.tsx b/frontend/code/src/Components/Play/index.tsx index 0a4a76c..aaa355e 100644 --- a/frontend/code/src/Components/Play/index.tsx +++ b/frontend/code/src/Components/Play/index.tsx @@ -40,20 +40,19 @@ export const Play = () => { }; return ( <> -

    -
    + Classic Gamemode - -
    - -
    + Extra Gamemode - -
    + />
    { const TOTPSecretKey = useMemo( - () => btoa(Math.random().toString(36)).substring(0, 16), + () => + btoa(Math.random().toString(36) + Math.random().toString(36)) + .toUpperCase() + .replace(/\+/g, "") + .replace(/\//g, "") + .replace(/=/g, "") + .substring(0, 16), [], ); diff --git a/frontend/code/src/setupTests.ts b/frontend/code/src/setupTests.ts deleted file mode 100644 index 1dd407a..0000000 --- a/frontend/code/src/setupTests.ts +++ /dev/null @@ -1,5 +0,0 @@ -// jest-dom adds custom jest matchers for asserting on DOM nodes. -// allows you to do things like: -// expect(element).toHaveTextContent(/react/i) -// learn more: https://github.com/testing-library/jest-dom -import "@testing-library/jest-dom"; diff --git a/nginx/default.conf b/nginx/default.conf index 4522e71..836eb5c 100644 --- a/nginx/default.conf +++ b/nginx/default.conf @@ -1,7 +1,7 @@ server { - listen 80; - listen [::]:80; - server_name test.reversablecode.com; + listen 80; + listen [::]:80; + gzip on; gzip_proxied any; gzip_comp_level 6; @@ -10,42 +10,42 @@ server { gzip_types text/css application/javascript application/json application/font-woff application/font-tff image/gif image/png image/svg+xml application/octet-stream; location / { - try_files $uri /index.html; + try_files $uri /index.html; - root /var/www/html/; - index index.html index.htm; + root /var/www/html/; + index index.html index.htm; } } + server { - listen 3001; + listen 3001; + listen [::]:3001; - server_name test.reversablecode.com; + location / { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; - gzip on; - gzip_proxied any; - gzip_comp_level 6; - gzip_buffers 16 8k; - gzip_http_version 1.1; - gzip_types text/css application/javascript application/json application/font-woff application/font-tff image/gif image/png image/svg+xml application/octet-stream; + proxy_pass http://backend:3001; - location / { - - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $host; - proxy_pass http://backend:3001/; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - location /socket.io/ { - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $host; - - proxy_pass http://backend:3004; - - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} + +server { + listen 3004; + listen [::]:3004; + + location / { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + + proxy_pass http://backend:3004; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } }