Updated front-end to match back-end rewrite
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
import React, {FunctionComponent} from "react";
|
import React, {FunctionComponent} from "react";
|
||||||
|
import {NoButton} from "./Button";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
cardString: string;
|
cardString: string;
|
||||||
handleClick?: (cardString: string) => void;
|
handleClick?: (cardString: string) => void;
|
||||||
isHidden?: boolean;
|
isHidden?: boolean;
|
||||||
isClickable?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Card: FunctionComponent<Props> = ({cardString, handleClick, isHidden, isClickable}) => {
|
const Card: FunctionComponent<Props> = ({cardString, handleClick, isHidden}) => {
|
||||||
const cardType = cardString.split(' ')[0].toLowerCase();
|
const cardType = cardString.split(' ')[0].toLowerCase();
|
||||||
const cardValue = cardString.split(' ')[1].toLowerCase();
|
const cardValue = cardString.split(' ')[1].toLowerCase();
|
||||||
|
|
||||||
@@ -30,9 +30,17 @@ const Card: FunctionComponent<Props> = ({cardString, handleClick, isHidden, isCl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (handleClick) {
|
||||||
|
return (
|
||||||
|
<NoButton className={"card"} onClick={handleCardClick}>
|
||||||
|
<img className="card__texture" src={cardSource()} alt={cardName}/>
|
||||||
|
</NoButton>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`card ${isClickable && 'card-clickable'}`}>
|
<div className={"card"}>
|
||||||
<img className="card__texture" src={cardSource()} alt={cardName} onClick={handleCardClick}/>
|
<img className="card__texture" src={cardSource()} alt={cardName}/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,10 @@ const Deck: FunctionComponent<Props> = ({currentCard, actionOnClick}) => {
|
|||||||
return (
|
return (
|
||||||
<div className="deck-container">
|
<div className="deck-container">
|
||||||
<div className="used-cards">
|
<div className="used-cards">
|
||||||
<p></p>
|
|
||||||
<Card cardString={currentCard}/>
|
<Card cardString={currentCard}/>
|
||||||
</div>
|
</div>
|
||||||
<div className="deck">
|
<div className="deck">
|
||||||
<p></p>
|
<Card cardString={"AA BB"} handleClick={handleClick} isHidden/>
|
||||||
<Card cardString={"AA BB"} handleClick={handleClick} isHidden isClickable/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import React, {FunctionComponent} from "react";
|
|||||||
import Deck from "./Deck";
|
import Deck from "./Deck";
|
||||||
import Hand from "./Hand";
|
import Hand from "./Hand";
|
||||||
import {GHButton} from "./Button";
|
import {GHButton} from "./Button";
|
||||||
import {GameAction, Player} from "../pages/Room";
|
import {Player, SocketMessage} from "../pages/Room";
|
||||||
|
|
||||||
export interface GameState {
|
export interface GameState {
|
||||||
Me: Player;
|
Me: Player;
|
||||||
CurrentState: string;
|
MyState: string;
|
||||||
Hand: string[];
|
Hand: string[];
|
||||||
CurrentCard: string;
|
CurrentCard: string;
|
||||||
CurrentPlayer: Player;
|
CurrentPlayer: Player;
|
||||||
@@ -15,7 +15,7 @@ export interface GameState {
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
gameState: GameState
|
gameState: GameState
|
||||||
handleGameAction: (action: GameAction) => void;
|
handleGameAction: (message: SocketMessage) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CHOICES = ['SPADES', 'HEARTS', 'DIAMONDS', 'CLUBS'];
|
const CHOICES = ['SPADES', 'HEARTS', 'DIAMONDS', 'CLUBS'];
|
||||||
@@ -23,15 +23,15 @@ const CHOICES = ['SPADES', 'HEARTS', 'DIAMONDS', 'CLUBS'];
|
|||||||
const Game: FunctionComponent<Props> = ({gameState, handleGameAction}) => {
|
const Game: FunctionComponent<Props> = ({gameState, handleGameAction}) => {
|
||||||
|
|
||||||
const handleChoice = (choice: string) => {
|
const handleChoice = (choice: string) => {
|
||||||
handleGameAction({Action: 'CHOOSE', Data: choice});
|
handleGameAction({Type: 'CHOOSE', Data: choice});
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDraw = () => {
|
const handleDraw = () => {
|
||||||
handleGameAction({Action: 'DRAW', Data: ""});
|
handleGameAction({Type: 'DRAW', Data: ""});
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCardSend = (cardString: string) => {
|
const handleCardSend = (cardString: string) => {
|
||||||
handleGameAction({Action: "PLAYCARD", Data: JSON.stringify({
|
handleGameAction({Type: "PLAY", Data: JSON.stringify({
|
||||||
CardType: cardString.split(' ')[0],
|
CardType: cardString.split(' ')[0],
|
||||||
CardValue: cardString.split(' ')[1]
|
CardValue: cardString.split(' ')[1]
|
||||||
})})
|
})})
|
||||||
@@ -70,7 +70,7 @@ const Game: FunctionComponent<Props> = ({gameState, handleGameAction}) => {
|
|||||||
<Hand hand={gameState.Hand} actionOnClick={handleCardSend}/>
|
<Hand hand={gameState.Hand} actionOnClick={handleCardSend}/>
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
gameState.CurrentState === 'CHOOSE' &&
|
gameState.MyState === 'CHOOSE' &&
|
||||||
CHOICES.map(choice => <GHButton key={choice} onClick={() => handleChoice(choice)}>{choice}</GHButton>)
|
CHOICES.map(choice => <GHButton key={choice} onClick={() => handleChoice(choice)}>{choice}</GHButton>)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,25 +3,24 @@ import Card from "./Card";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
hand: string[];
|
hand: string[];
|
||||||
actionOnClick: (cardString: string) => void;
|
actionOnClick?: (cardString: string) => void;
|
||||||
isHidden?: boolean;
|
isHidden?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Hand: FunctionComponent<Props> = ({hand, actionOnClick, isHidden}) => {
|
const Hand: FunctionComponent<Props> = ({hand, actionOnClick, isHidden}) => {
|
||||||
|
|
||||||
const isMyHand = !isHidden;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="hand">
|
<ul className="hand">
|
||||||
{
|
{
|
||||||
hand.map((card, index) => {
|
hand.map((card, index) => {
|
||||||
return (
|
return (
|
||||||
<Card key={index} cardString={card} handleClick={actionOnClick} isHidden={!isMyHand}
|
<li key={card} className={"hand__item"}>
|
||||||
isClickable={isMyHand}/>
|
<Card cardString={card} handleClick={actionOnClick} isHidden={isHidden}/>
|
||||||
|
</li>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</div>
|
</ul>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ const MainLobby = () => {
|
|||||||
<div className={"main-lobby__container"}>
|
<div className={"main-lobby__container"}>
|
||||||
<NoButton className={"main-lobby__container-button"} onClick={handleCreateRoom}>
|
<NoButton className={"main-lobby__container-button"} onClick={handleCreateRoom}>
|
||||||
<h2 className={"mau"}>Host Game</h2>
|
<h2 className={"mau"}>Host Game</h2>
|
||||||
<Card cardString={'SPADES ACE'} isClickable/>
|
<Card cardString={'SPADES ACE'}/>
|
||||||
</NoButton>
|
</NoButton>
|
||||||
<NoButton className={"main-lobby__container-button"} onClick={() => navigateTo('/rooms')}>
|
<NoButton className={"main-lobby__container-button"} onClick={() => navigateTo('/rooms')}>
|
||||||
<h2 className={"mau"}>Join Game</h2>
|
<h2 className={"mau"}>Join Game</h2>
|
||||||
<Card cardString={'SPADES ACE'} isHidden isClickable/>
|
<Card cardString={'SPADES ACE'} isHidden/>
|
||||||
</NoButton>
|
</NoButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,14 +13,13 @@ export interface Player {
|
|||||||
CardsLeft: number;
|
CardsLeft: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SocketMessage {
|
export interface SocketMessage {
|
||||||
Type: string;
|
Type: string;
|
||||||
Payload: any;
|
Data: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GameAction {
|
interface JoinLeaveMessage {
|
||||||
Action: string;
|
ChatMessage: string;
|
||||||
Data: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Room = () => {
|
const Room = () => {
|
||||||
@@ -35,7 +34,6 @@ const Room = () => {
|
|||||||
const WS_URL = `${process.env.REACT_APP_WEBSOCKET_URL}/room/${roomId}/${playerName}`;
|
const WS_URL = `${process.env.REACT_APP_WEBSOCKET_URL}/room/${roomId}/${playerName}`;
|
||||||
|
|
||||||
const [gameState, setGameState] = React.useState<GameState | undefined>(undefined);
|
const [gameState, setGameState] = React.useState<GameState | undefined>(undefined);
|
||||||
const [lobbyState, setLobbyState] = React.useState<string>("");
|
|
||||||
const [winner, setWinner] = React.useState<string | undefined>(undefined);
|
const [winner, setWinner] = React.useState<string | undefined>(undefined);
|
||||||
|
|
||||||
const chatRef = React.useRef<HTMLOListElement>(null);
|
const chatRef = React.useRef<HTMLOListElement>(null);
|
||||||
@@ -59,15 +57,11 @@ const Room = () => {
|
|||||||
onOpen: () => {
|
onOpen: () => {
|
||||||
console.log('WebSocket connection established.');
|
console.log('WebSocket connection established.');
|
||||||
},
|
},
|
||||||
onMessage: (event) => {
|
onMessage: (messageEvent) => {
|
||||||
const data = JSON.parse(event.data);
|
const data: SocketMessage = JSON.parse(messageEvent.data);
|
||||||
const payload = JSON.parse(data.Payload);
|
const payload = JSON.parse(data.Data);
|
||||||
switch (data.Type) {
|
switch (data.Type) {
|
||||||
case 'LOBBY':
|
|
||||||
setLobbyState(data.Type);
|
|
||||||
break;
|
|
||||||
case 'GAME':
|
case 'GAME':
|
||||||
setLobbyState(data.Type);
|
|
||||||
setGameState(payload);
|
setGameState(payload);
|
||||||
break;
|
break;
|
||||||
case 'CHAT':
|
case 'CHAT':
|
||||||
@@ -77,6 +71,12 @@ const Room = () => {
|
|||||||
setWinner(payload.Name)
|
setWinner(payload.Name)
|
||||||
setGameState(undefined);
|
setGameState(undefined);
|
||||||
break;
|
break;
|
||||||
|
case "JOIN":
|
||||||
|
addChatMessage({Sender: "System", Message: (JSON.parse(data.Data) as JoinLeaveMessage).ChatMessage});
|
||||||
|
break;
|
||||||
|
case "LEAVE":
|
||||||
|
addChatMessage({Sender: "System", Message: (JSON.parse(data.Data) as JoinLeaveMessage).ChatMessage});
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
console.log('Unknown message type:', data.Type);
|
console.log('Unknown message type:', data.Type);
|
||||||
}
|
}
|
||||||
@@ -91,18 +91,14 @@ const Room = () => {
|
|||||||
websocket.sendMessage(JSON.stringify(message));
|
websocket.sendMessage(JSON.stringify(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleGameAction = (action: GameAction) => {
|
|
||||||
handleSend({Type: "GAME", Payload: JSON.stringify(action)});
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleLobbyAction = (action: string) => {
|
const handleLobbyAction = (action: string) => {
|
||||||
handleSend({Type: "LOBBY", Payload: JSON.stringify(action)});
|
handleSend({Type: "LOBBY", Data: JSON.stringify(action)});
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleChatMessage = (chatMessage: string) => {
|
const handleChatMessage = (chatMessage: string) => {
|
||||||
handleSend({
|
handleSend({
|
||||||
Type: "CHAT",
|
Type: "CHAT",
|
||||||
Payload: chatMessage
|
Data: chatMessage
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,8 +126,8 @@ const Room = () => {
|
|||||||
<main className={"room-main"}>
|
<main className={"room-main"}>
|
||||||
{
|
{
|
||||||
gameState ?
|
gameState ?
|
||||||
<Game gameState={gameState} handleGameAction={handleGameAction}/>
|
<Game gameState={gameState} handleGameAction={handleSend}/>
|
||||||
: lobbyState === 'LOBBY' &&
|
:
|
||||||
<Lobby winner={winner} handleLobbyAction={handleLobbyAction}/>
|
<Lobby winner={winner} handleLobbyAction={handleLobbyAction}/>
|
||||||
}
|
}
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -2,10 +2,6 @@
|
|||||||
width: 100px;
|
width: 100px;
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
|
|
||||||
&-clickable {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__texture {
|
&__texture {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -5,4 +5,8 @@
|
|||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user