Skip to content

Commit

Permalink
#13 highlight current player
Browse files Browse the repository at this point in the history
  • Loading branch information
stoerti committed Aug 16, 2024
1 parent 23217e0 commit 521ff9c
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 104 deletions.
6 changes: 4 additions & 2 deletions frontend/src/domain/GameModel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,15 @@ export class Game {

public onGameCanceled(event: GameCanceledEvent): Game {
return this.copyWith({
status: GameStatus.CANCELED
status: GameStatus.CANCELED,
currentQuestion: undefined
})
}

public onGameEnded(event: GameEndedEvent): Game {
return this.copyWith({
status: GameStatus.ENDED
status: GameStatus.ENDED,
currentQuestion: undefined
})
}

Expand Down
48 changes: 3 additions & 45 deletions frontend/src/pages/game/GameFinished.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import {Game} from "../../domain/GameModel";
import React from "react";
import {AppBar, Box, Button, Stack, Table, TableBody, TableCell, TableHead, TableRow, Toolbar, Typography} from "@mui/material";
import {AppBar, Box, Button, Stack, Toolbar, Typography} from "@mui/material";
import Logout from "@mui/icons-material/Logout";
import EmojiEvents from "@mui/icons-material/EmojiEvents";
import {amber, brown, grey} from "@mui/material/colors";
import {Scoreboard} from "./gameroom/Scoreboard.tsx";

export type GameFinishedPageProps = {
game: Game,
Expand Down Expand Up @@ -36,48 +35,7 @@ export const GameFinishedPage = (props: GameFinishedPageProps) => {
<Button sx={{margin: 'auto'}} startIcon={<Logout/>} variant="contained"
onClick={props.onClickLeaveGame}>Leave game</Button>
</div>
<Table aria-label="simple table" sx={{width: '100%'}}>
<TableHead>
<TableRow>
<TableCell></TableCell>
<TableCell>Name</TableCell>
<TableCell align="right">Points</TableCell>
</TableRow>
</TableHead>
<TableBody>
{[...props.game.players].sort((u1, u2) => u2.points - u1.points).map((row, index) => {
let cup;
switch (index) {
case 0:
cup = <EmojiEvents sx={{color: amber[500]}}/>;
break;
case 1:
cup = <EmojiEvents sx={{color: grey[500]}}/>;
break;
case 2:
cup = <EmojiEvents sx={{color: brown[700]}}/>;
break;
}
return (
<TableRow
key={row.id}
sx={{'&:last-child td, &:last-child th': {border: 0}}}
>
<TableCell align="left">{cup}</TableCell>
<TableCell component="th" scope="row">
<Typography
variant="body1"
component="div"
>
{row.name}
</Typography>
</TableCell>
<TableCell align="right">{row.points}</TableCell>
</TableRow>
)
})}
</TableBody>
</Table>
<Scoreboard game={props.game} />
</Stack>
</Box>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export const ModeratorGameRoomPanel = ({game}: ModeratorGameRoomPanelProps) => {
)
} else if (question.status === QuestionStatus.SCORED) {
return (
<Stack spacing={2}>
<Stack spacing={2} alignItems={"center"}>
<QuestionPhrasePanel gameQuestion={question}/>
<CorrectAnswerContainer correctAnswer={question.question.correctAnswer}/>
<div style={{display: "flex", alignItems: "center"}}>
Expand Down
18 changes: 8 additions & 10 deletions frontend/src/pages/game/gameroom/PlayerGameRoomPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const PlayerGameRoomPanel = ({game, player}: PlayerGameRoomPanelProps) =>
container = <div>Waiting for first question</div>
} else if (question.status === QuestionStatus.OPEN) {
if (question.hasPlayerAlreadyAnswered(player.id)) {
container = <Stack spacing={2}>
return <Stack spacing={2} alignItems={"center"}>
<QuestionPhrasePanel gameQuestion={question}/>
<Paper sx={{padding: 2}}>
<Box sx={{display: 'block', m: 'auto', alignContent: 'center'}}>
Expand Down Expand Up @@ -57,7 +57,7 @@ export const PlayerGameRoomPanel = ({game, player}: PlayerGameRoomPanelProps) =>
}
}

container = <QuestionContainer gameQuestion={question} onAnswerQuestion={onAnswerQuestion}/>
return <QuestionContainer gameQuestion={question} onAnswerQuestion={onAnswerQuestion}/>
} else if (question.questionMode === GameQuestionMode.BUZZER) {
const onBuzzQuestion = async () => {
try {
Expand All @@ -71,14 +71,13 @@ export const PlayerGameRoomPanel = ({game, player}: PlayerGameRoomPanelProps) =>
}
}
}
container = <BuzzerQuestionContainer gameQuestion={question} player={player} onBuzzQuestion={onBuzzQuestion}/>
return <BuzzerQuestionContainer gameQuestion={question} player={player} onBuzzQuestion={onBuzzQuestion}/>
} else {
container = <div>Unknown gameQuestionMode {question.questionMode}</div>
return <div>Unknown gameQuestionMode {question.questionMode}</div>
}
}
} else if (question.status === QuestionStatus.CLOSED) {
container =
<Stack spacing={2}>
return <Stack spacing={2} alignItems={"center"}>
<QuestionPhrasePanel gameQuestion={question}/>
<CorrectAnswerContainer correctAnswer={question.question.correctAnswer} />
<Table aria-label="simple table">
Expand Down Expand Up @@ -128,19 +127,18 @@ export const PlayerGameRoomPanel = ({game, player}: PlayerGameRoomPanelProps) =>
onClick={onNextQuestion}>Next question</Button>
</div>
}
container =
<Stack spacing={2}>
return <Stack spacing={2} alignItems={"center"}>
<QuestionPhrasePanel gameQuestion={question}/>
<CorrectAnswerContainer correctAnswer={question.question.correctAnswer} />
{nextButton}
<Scoreboard game={game} />
</Stack>

} else {
container = <div>Unknown state</div>
return <div>Unknown state</div>
}

return <Box sx={{ width: '100%'}}>
return <Box sx={{ width: '100%', alignItems: 'center'}}>
{container}
</Box>
}
126 changes: 80 additions & 46 deletions frontend/src/pages/game/gameroom/Scoreboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Cancel from "@mui/icons-material/Cancel";
import React, {useState} from "react";
import {ArrowBack, ArrowForward} from "@mui/icons-material";
import useWindowDimensions from "../../../hooks/useWindowDimensions.tsx";
import Cookies from "js-cookie";


const comparePlayersByPointsAndName = function (p1: Player, p2: Player): number {
Expand All @@ -28,56 +29,89 @@ export type ScoreboardPageProps = {

const ScoreboardPage = ({game, page, pageSize}: ScoreboardPageProps) => {
const lastQuestion = game.currentQuestion
const username = Cookies.get("username")

const first = page * pageSize
const last = (page + 1) * pageSize

return <Table style={{width: '100%', minWidth: 400, maxWidth: 1000}} size={"small"} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell></TableCell>
<TableCell>Username</TableCell>
<TableCell>Answer</TableCell>
<TableCell align="right" colSpan={2}>Points</TableCell>
</TableRow>
</TableHead>
<TableBody>
{[...game.players].sort(comparePlayersByPointsAndName)
.slice(first, last)
.map((player, index) => {
let icon
let questionPoints
const playerAnswer = lastQuestion?.answers.find(p => p.gamePlayerId === player.id)

if (playerAnswer !== undefined) {
icon = playerAnswer.points > 0 ? <CheckCircle sx={{verticalAlign: 'bottom'}} color='success'/> :
<Cancel sx={{verticalAlign: 'bottom'}} color='error'/>
questionPoints = "+" + playerAnswer.points
} else {
icon = <Cancel sx={{verticalAlign: 'bottom'}} color='error'/>
questionPoints = "+0"
}

return (
<TableRow key={player.id} sx={{'&:last-child td, &:last-child th': {border: 0}}}>
<TableCell width={20} align="left">#{index + 1 + page * pageSize}</TableCell>
<TableCell component="td" scope="row">
<Typography variant="body1" component="div">
{player.name}
</Typography>
</TableCell>
<TableCell component="td" scope="row">
<Typography variant="body1">
{icon} {playerAnswer?.answer}
</Typography>
</TableCell>
<TableCell width={10} align="right">{questionPoints}</TableCell>
<TableCell width={10} align="right">{player.points}</TableCell>
</TableRow>
)
})}
</TableBody>
</Table>
if (lastQuestion !== undefined) {
return <Table style={{width: '100%', minWidth: 400, maxWidth: 1000}} size={"small"} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell></TableCell>
<TableCell>Username</TableCell>
<TableCell>Answer</TableCell>
<TableCell align="right" colSpan={2}>Points</TableCell>
</TableRow>
</TableHead>
<TableBody>
{[...game.players].sort(comparePlayersByPointsAndName)
.slice(first, last)
.map((player, index) => {
let icon
let questionPoints
const playerAnswer = lastQuestion?.answers.find(p => p.gamePlayerId === player.id)

if (playerAnswer !== undefined) {
icon = playerAnswer.points > 0 ? <CheckCircle sx={{verticalAlign: 'bottom'}} color='success'/> :
<Cancel sx={{verticalAlign: 'bottom'}} color='error'/>
questionPoints = "+" + playerAnswer.points
} else {
icon = <Cancel sx={{verticalAlign: 'bottom'}} color='error'/>
questionPoints = "+0"
}

const fontWeight = player.name === username ? 'bold' : 'normal'

return (
<TableRow key={player.id} sx={{'&:last-child td, &:last-child th': {border: 0}}}>
<TableCell width={20} align="left" sx={{fontWeight: fontWeight}}>#{index + 1 + page * pageSize}</TableCell>
<TableCell>
<Typography variant="body1" component="div" sx={{fontWeight: fontWeight}}>
{player.name}
</Typography>
</TableCell>
<TableCell>
<Typography variant="body1" sx={{fontWeight: fontWeight}}>
{icon} {playerAnswer?.answer}
</Typography>
</TableCell>
<TableCell width={10} align="right" sx={{fontWeight: fontWeight}}>{questionPoints}</TableCell>
<TableCell width={10} align="right" sx={{fontWeight: fontWeight}}>{player.points}</TableCell>
</TableRow>
)
})}
</TableBody>
</Table>
} else {
return <Table style={{width: '100%', minWidth: 400, maxWidth: 1000}} size={"small"} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell></TableCell>
<TableCell>Username</TableCell>
<TableCell align="right">Points</TableCell>
</TableRow>
</TableHead>
<TableBody>
{[...game.players].sort(comparePlayersByPointsAndName)
.slice(first, last)
.map((player, index) => {
const fontWeight = player.name === username ? 'bold' : 'normal'
return (
<TableRow key={player.id} sx={{'&:last-child td, &:last-child th': {border: 0}}}>
<TableCell width={20} align="left" sx={{fontWeight: fontWeight}}>#{index + 1 + page * pageSize}</TableCell>
<TableCell component="td" scope="row">
<Typography variant="body1" component="div" sx={{fontWeight: fontWeight}}>
{player.name}
</Typography>
</TableCell>
<TableCell width={10} align="right" sx={{fontWeight: fontWeight}}>{player.points}</TableCell>
</TableRow>
)
})}
</TableBody>
</Table>
}

}

Expand Down

0 comments on commit 521ff9c

Please sign in to comment.