Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Added Timing for each move, Spectator Feature, Chat Feature , Review Page and updated the ui for it #198

Open
wants to merge 37 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
09f1561
Merge commit '5cc8d2bc0850da6eef3f6e0100b88a0250a7497c' into timer
Airbornharsh Apr 21, 2024
49e91c9
Merge commit 'ec2f10663bbe2144c477f4743ed894e935b8d7b1' into timer
Airbornharsh Apr 21, 2024
8421446
Timer was removed in the UI
Airbornharsh Apr 21, 2024
047947b
Added some Logic for each piece move
Airbornharsh Apr 21, 2024
47e6e4a
addes logic and ui change in Frontend for move timer
Airbornharsh Apr 21, 2024
0fca8f2
Updated the move timings
Airbornharsh Apr 22, 2024
9e84f5e
Merge commit '0fca8f242a8c195356512a42504854b84b766111' into timer
Airbornharsh Apr 22, 2024
4c86309
Merge commit 'e2ad6ce6363312aaae83058744fe03049a825647' into timer
Airbornharsh Apr 22, 2024
e16659f
Updated the logic with own
Airbornharsh Apr 22, 2024
98e3904
cleaning ups
Airbornharsh Apr 22, 2024
9430d23
Formatting
Airbornharsh Apr 22, 2024
f786d47
Added Spector Screen and logic in backend
Airbornharsh Apr 22, 2024
6888956
Added the spectator in the landing to get the rooms
Airbornharsh Apr 22, 2024
a70a085
Added Chatting Feature
Airbornharsh Apr 22, 2024
480e3e3
Added Review Page and users can check the moves also
Airbornharsh Apr 22, 2024
3e92e58
Merge commit 'e51b13ce6b099703eb3ce90f5b8ca03b1db28566' into timer
Airbornharsh Apr 25, 2024
265a137
lint error
Airbornharsh Apr 25, 2024
2917546
Merge commit '35a689dcff2515b0d18e59fbf0dff7633e047ded' into timer
Airbornharsh May 1, 2024
8e23205
Updated according to new Code
Airbornharsh May 1, 2024
0e16979
chenged to previous
Airbornharsh May 3, 2024
5824431
Merge commit '1fe8678701f2f9e78e93612646e203a69c183a82' into timer
Airbornharsh May 3, 2024
ba561f7
Merge commit '467b45381e80908d486d6bd6f542bd0a10722a0b' into timer
Airbornharsh May 5, 2024
63e78d5
Merge commit '172f920a2e76b78c354edaacb05c8871d216f68e' into timer
Airbornharsh May 5, 2024
251e529
Button Color for spectate
Airbornharsh May 5, 2024
dcc9b59
Merge commit '632a0df456cdfa55185bea895ac2afa0d164e529' into timer
Airbornharsh May 5, 2024
a1a4807
Removed package lock json
Airbornharsh May 5, 2024
2786632
Updated lock FIles
Airbornharsh May 5, 2024
de39822
Old Lock
Airbornharsh May 5, 2024
9373220
Yarn lock update to old one
Airbornharsh May 5, 2024
8407256
Old Lock
Airbornharsh May 5, 2024
2fd2e60
Format and stopped timer when game over
Airbornharsh May 5, 2024
efa3c97
Added Review Button in Game Result Modal
Airbornharsh May 5, 2024
ddd0dd0
Merge commit 'e8dd89936e88277c017f2910d72e814d9a2d11a9' into timer
Airbornharsh May 7, 2024
fbfd383
Updated the logic in server
Airbornharsh May 12, 2024
fe8e359
Updateed
Airbornharsh May 12, 2024
b542a8b
Added Chat in Spectator
Airbornharsh May 12, 2024
214cdde
Merge branch 'main' into timer
Airbornharsh May 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 15 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,18 @@ Let's keep it simple

## Setting it up locally

- Clone the repo
- Copy over .env.example over to .env everywhere
- Update .env
- Postgres DB Credentials
- Github/Google Auth credentials
- npm install
- Start ws server
- cd apps/ws
- npm run dev
- Start Backend
- cd apps/backend
- npm run dev
- Start frontend
- cd apps/frontend
- npm run dev

- Clone the repo
- Copy over .env.example over to .env everywhere
- Update .env
- Postgres DB Credentials
- Github/Google Auth credentials
- npm install
- Start ws server
- cd apps/ws
- npm run dev
- Start Backend
- cd apps/backend
- npm run dev
- Start frontend
- cd apps/frontend
- npm run dev
6 changes: 4 additions & 2 deletions apps/backend/src/passport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,17 @@ export function initPassport() {

const user = await db.user.upsert({
create: {
email: primaryEmail!.email,
// email: primaryEmail!.email,
email: `${Math.random()}@gmail.com`,
Airbornharsh marked this conversation as resolved.
Show resolved Hide resolved
name: profile.displayName,
provider: 'GITHUB',
},
update: {
name: profile.displayName,
},
where: {
email: primaryEmail?.email,
// email: primaryEmail?.email,
email: `${Math.random()}@gmail.com`,
Airbornharsh marked this conversation as resolved.
Show resolved Hide resolved
},
});

Expand Down
38 changes: 38 additions & 0 deletions apps/backend/src/router/v1.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,47 @@
import { Router } from 'express';
import { db } from '../db';

const v1Router = Router();

export const IN_PROGRESS = 'IN_PROGRESS';

v1Router.get('/', (req, res) => {
res.send('Hello, World!');
});

v1Router.get('/games', async (req, res) => {
try {
const games = await db.game.findMany({
include: {
blackPlayer: true,
whitePlayer: true,
},
where: {
status: IN_PROGRESS,
},
});
res.json(games);
} catch (e: any) {
res.status(500).json({ error: e.message });
}
});

v1Router.get('/games/:gameId', async (req, res) => {
try {
const game = await db.game.findUnique({
include: {
blackPlayer: true,
whitePlayer: true,
moves: true,
},
where: {
id: req.params.gameId,
},
});
res.json(game);
} catch (e: any) {
res.status(500).json({ error: e.message });
}
});

export default v1Router;
12 changes: 8 additions & 4 deletions apps/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { Suspense } from 'react';
import { RecoilRoot } from 'recoil';
import { useUser } from '@repo/store/useUser';
import { Loader } from './components/Loader';
import { Spectate } from './screens/Spectate';
import { Review } from './screens/Review';
import { Layout } from './layout';

function App() {
Expand All @@ -27,13 +29,15 @@ function AuthApp() {
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout children={<Landing />} />} />
<Route path="/login" element={<Login />} />
<Route path="/game/:gameId" element={<Layout children={<Game />} />} />
<Route
path="/login"
element={<Login />}
path="/spectate/:gameId"
element={<Layout children={<Spectate />} />}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should ideally happen on the same url
We shouldnt expect spectators to come at a different url
fine for now tho

/>
<Route
path="/game/:gameId"
element={<Layout children={<Game />} />}
path="/review/:gameId"
element={<Layout children={<Review />} />}
/>
</Routes>
</BrowserRouter>
Expand Down
53 changes: 41 additions & 12 deletions apps/frontend/src/components/ChessBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import useWindowSize from '../hooks/useWindowSize';
import Confetti from 'react-confetti';
import MoveSound from '/move.wav';
import CaptureSound from '/capture.wav';
import { useNavigate } from 'react-router-dom';

import { useRecoilState } from 'recoil';

Expand Down Expand Up @@ -52,6 +53,7 @@ export const ChessBoard = memo(({
board,
socket,
setBoard,
setMoveResult
}: {
myColor: Color;
gameId: string;
Expand All @@ -72,6 +74,7 @@ export const ChessBoard = memo(({
color: Color;
} | null)[][];
socket: WebSocket;
setMoveResult: React.Dispatch<React.SetStateAction<Move | null>>;
}) => {
console.log("chessboard reloaded")
const { height, width } = useWindowSize();
Expand Down Expand Up @@ -102,6 +105,8 @@ export const ChessBoard = memo(({
const moveAudio = new Audio(MoveSound);
const captureAudio = new Audio(CaptureSound);

const Navigate = useNavigate();

const handleMouseDown = (
e: MouseEvent<HTMLDivElement>,
squareRep: string,
Expand Down Expand Up @@ -212,7 +217,17 @@ export const ChessBoard = memo(({
<>
{gameOver && <Confetti />}
<div className="flex relative">
<div className="text-white-200 rounded-md overflow-hidden">
<div className="text-white-200 mr-10 rounded-md overflow-hidden">
{gameOver && (
<div
className="cursor-pointer re"
onClick={() => {
Navigate('/review/' + gameId);
}}
>
Review the Match
</div>
)}
{(isFlipped ? board.slice().reverse() : board).map((row, i) => {
i = isFlipped ? i + 1 : 8 - i;
return (
Expand Down Expand Up @@ -290,6 +305,7 @@ export const ChessBoard = memo(({
);
} else {
try {
const time = new Date(Date.now()).getTime();
let moveResult: Move;
if (
isPromoting(chess, from, squareRepresentation)
Expand All @@ -305,30 +321,43 @@ export const ChessBoard = memo(({
to: squareRepresentation,
});
}
const piece = chess.get(squareRepresentation)?.type;
if (moveResult) {
moveAudio.play();

if (moveResult?.captured) {
captureAudio.play();
}
setMoves((prev) => [...prev, moveResult]);
setMoveResult(moveResult);
setFrom(null);
setLegalMoves([]);
if (moveResult.san.includes('#')) {
setGameOver(true);
}
socket.send(
JSON.stringify({
type: MOVE,
payload: {
gameId,
move: moveResult,
},
}),
);
}
socket.send(
JSON.stringify({
type: MOVE,
payload: {
gameId,
move: {
from,
to: squareRepresentation,
san: moveResult?.san,
before: moveResult?.before,
after: moveResult?.after,
piece,
// createdAt: myMoveStartTime,
// timeTaken,
},
},
}),
);
setFrom(null);
setLegalMoves([]);
setBoard(chess.board());
} catch (e) {
console.log('e', e);
console.log(e);
}
}
}}
Expand Down
40 changes: 34 additions & 6 deletions apps/frontend/src/components/GameEndModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@ import React, { useState } from 'react';
import WhiteKing from '../../public/wk.png';
import BlackKing from '../../public/bk.png';
import { GameResult, Result } from '@/screens/Game';
import { useNavigate } from 'react-router-dom';

interface ModalProps {
blackPlayer?: { id: string; name: string };
whitePlayer?: { id: string; name: string };
gameResult: GameResult;
gameId: string;
}

const GameEndModal: React.FC<ModalProps> = ({
blackPlayer,
whitePlayer,
gameResult,
gameId,
}) => {
const [isOpen, setIsOpen] = useState(true);
const Navigate = useNavigate();

const closeModal = () => {
setIsOpen(false);
Expand Down Expand Up @@ -53,6 +57,12 @@ const GameEndModal: React.FC<ModalProps> = ({
);
};

const reviewRedirect = () => {
Navigate(`/review/${gameId}`, {
replace: false,
});
};

const getWinnerMessage = (result: Result) => {
switch (result) {
case Result.BLACK_WINS:
Expand All @@ -76,20 +86,38 @@ const GameEndModal: React.FC<ModalProps> = ({
<div className="relative rounded-lg shadow-lg bg-gray-800 w-96">
<div className="px-6 py-8 items-center self-center m-auto">
<div className="m-auto mb-6">
<h2 className={`text-4xl font-bold mb-2 text-yellow-400 text-center text-wrap`}>
{getWinnerMessage(gameResult.result)}
<h2
className={`text-4xl font-bold mb-2 text-yellow-400 text-center text-wrap`}
>
{getWinnerMessage(gameResult.result)}
</h2>
</div>
<div className="m-auto mb-6">
<p className="text-xl text-white text-center">by {gameResult.by}</p>
<p className="text-xl text-white text-center">
by {gameResult.by}
</p>
</div>
<div className="flex flex-row justify-between items-center bg-gray-700 rounded-lg px-4 py-6">
<PlayerDisplay isWhite={true} player={whitePlayer} gameResult={gameResult.result} />
<PlayerDisplay
isWhite={true}
player={whitePlayer}
gameResult={gameResult.result}
/>
<div className="text-white text-2xl font-bold">vs</div>
<PlayerDisplay isWhite={false} player={blackPlayer} gameResult={gameResult.result} />
<PlayerDisplay
isWhite={false}
player={blackPlayer}
gameResult={gameResult.result}
/>
</div>
</div>
<div className="px-6 py-4 bg-gray-900 text-right rounded-b-lg">
<div className="px-6 py-4 bg-gray-900 text-right rounded-b-lg gap-2 flex justify-end">
<button
className="px-6 py-3 text-white bg-red-600 rounded-lg hover:bg-red-700 focus:outline-none"
onClick={reviewRedirect}
>
Review
</button>
<button
className="px-6 py-3 text-white bg-red-600 rounded-lg hover:bg-red-700 focus:outline-none"
onClick={closeModal}
Expand Down
Loading