@@ -2,17 +2,14 @@ import React from 'react';
|
|||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from 'react-dom/client';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
import ThemeContextProvider from "./utils/contexts/ThemeContext";
|
import ThemeContextProvider from "./utils/contexts/ThemeContext";
|
||||||
import AuthContextProvider from "./utils/contexts/AuthContext";
|
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(
|
const root = ReactDOM.createRoot(
|
||||||
document.getElementById('root') as HTMLElement
|
document.getElementById('root') as HTMLElement
|
||||||
);
|
);
|
||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<AuthContextProvider>
|
<ThemeContextProvider>
|
||||||
<ThemeContextProvider>
|
<App/>
|
||||||
<App/>
|
</ThemeContextProvider>
|
||||||
</ThemeContextProvider>
|
|
||||||
</AuthContextProvider>
|
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
);
|
);
|
||||||
46
src/layout/components/Game.tsx
Normal file
46
src/layout/components/Game.tsx
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import React, {FunctionComponent} from "react";
|
||||||
|
import Deck from "./Deck";
|
||||||
|
import Hand from "./Hand";
|
||||||
|
|
||||||
|
interface GameState {
|
||||||
|
PlayerName: string;
|
||||||
|
Hand: string[];
|
||||||
|
CurrentCard: string;
|
||||||
|
CurrentPlayer: string;
|
||||||
|
Players: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
gameState: GameState
|
||||||
|
handleCardSend: (cardString: string) => void;
|
||||||
|
handleDraw: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Game:FunctionComponent<Props> = ({gameState, handleCardSend, handleDraw}) => {
|
||||||
|
return (
|
||||||
|
<div className="game">
|
||||||
|
{
|
||||||
|
gameState.CurrentCard &&
|
||||||
|
<Deck currentCard={gameState.CurrentCard} actionOnClick={handleDraw}/>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
gameState.Hand &&
|
||||||
|
<Hand hand={gameState.Hand} actionOnClick={handleCardSend}/>
|
||||||
|
}
|
||||||
|
<ul>
|
||||||
|
{
|
||||||
|
gameState.Players &&
|
||||||
|
gameState.Players.map((player, index) => {
|
||||||
|
const isCurrentPlayer = player === gameState.CurrentPlayer;
|
||||||
|
const isMe = player === gameState.PlayerName;
|
||||||
|
return <li key={index} style={{fontWeight: isCurrentPlayer ? 'bold' : 'normal'}}>
|
||||||
|
{player} {isMe && '(You)'}
|
||||||
|
</li>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Game;
|
||||||
@@ -3,8 +3,7 @@ import React from "react";
|
|||||||
import {useNavigate, useParams} from "react-router";
|
import {useNavigate, useParams} from "react-router";
|
||||||
import {GHButton} from "../components/Button";
|
import {GHButton} from "../components/Button";
|
||||||
import useTitle from "../../utils/hooks/TitleHook";
|
import useTitle from "../../utils/hooks/TitleHook";
|
||||||
import Hand from "../components/Hand";
|
import Game from "../components/Game";
|
||||||
import Deck from "../components/Deck";
|
|
||||||
|
|
||||||
interface GameState {
|
interface GameState {
|
||||||
PlayerName: string;
|
PlayerName: string;
|
||||||
@@ -14,6 +13,16 @@ interface GameState {
|
|||||||
Players: string[];
|
Players: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ChatMessage {
|
||||||
|
PlayerName: string;
|
||||||
|
Message: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SocketMessage {
|
||||||
|
Type: string;
|
||||||
|
Payload: any;
|
||||||
|
}
|
||||||
|
|
||||||
const Room = () => {
|
const Room = () => {
|
||||||
|
|
||||||
useTitle('Mau!');
|
useTitle('Mau!');
|
||||||
@@ -31,6 +40,8 @@ const Room = () => {
|
|||||||
CurrentPlayer: '',
|
CurrentPlayer: '',
|
||||||
Players: []
|
Players: []
|
||||||
});
|
});
|
||||||
|
const [chatMessages, setChatMessages] = React.useState<ChatMessage[]>([]);
|
||||||
|
const [chatInput, setChatInput] = React.useState<string>('');
|
||||||
|
|
||||||
const websocket = useWebSocket(WS_URL, {
|
const websocket = useWebSocket(WS_URL, {
|
||||||
onOpen: () => {
|
onOpen: () => {
|
||||||
@@ -38,7 +49,9 @@ const Room = () => {
|
|||||||
},
|
},
|
||||||
onMessage: (event) => {
|
onMessage: (event) => {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
setGameState(data);
|
const payload = JSON.parse(data.Payload);
|
||||||
|
if (data.Type === 'GAME') setGameState(payload);
|
||||||
|
if (data.Type === 'CHAT') setChatMessages(prev => [...prev, payload]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -48,44 +61,51 @@ const Room = () => {
|
|||||||
navigateTo('/');
|
navigateTo('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleSend = (message: SocketMessage) => {
|
||||||
|
websocket.sendMessage(JSON.stringify(message));
|
||||||
|
}
|
||||||
|
|
||||||
const handleCardSend = (card: string) => {
|
const handleCardSend = (card: string) => {
|
||||||
const formattedAction = JSON.stringify({
|
handleSend({
|
||||||
Action: "PLAYCARD",
|
Type: "GAME",
|
||||||
Data: JSON.stringify({CardType: card.split(' ')[0], CardValue: card.split(' ')[1]})
|
Payload: JSON.stringify({
|
||||||
});
|
Action: "PLAYCARD",
|
||||||
websocket.sendMessage(formattedAction);
|
Data: JSON.stringify({
|
||||||
|
CardType: card.split(' ')[0],
|
||||||
|
CardValue: card.split(' ')[1]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDraw = () => {
|
const handleDraw = () => {
|
||||||
const formattedAction = JSON.stringify({
|
handleSend({
|
||||||
Action: "DRAW",
|
Type: "GAME",
|
||||||
Data: ""
|
Payload: JSON.stringify({
|
||||||
|
Action: "DRAW",
|
||||||
|
Data: ""
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChat = (message: string) => {
|
||||||
|
handleSend({
|
||||||
|
Type: "CHAT",
|
||||||
|
Payload: message
|
||||||
});
|
});
|
||||||
websocket.sendMessage(formattedAction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h1>Room {roomId}</h1>
|
<h1>Room {roomId}</h1>
|
||||||
<GHButton onClick={handleLeaveRoom}>Leave Room</GHButton>
|
<GHButton onClick={handleLeaveRoom}>Leave Room</GHButton>
|
||||||
{
|
<Game gameState={gameState} handleCardSend={handleCardSend} handleDraw={handleDraw}/>
|
||||||
gameState.CurrentCard &&
|
<input type="text" placeholder={"Chat"} value={chatInput} onChange={(e) => setChatInput(e.target.value)} />
|
||||||
<Deck currentCard={gameState.CurrentCard} actionOnClick={handleDraw}/>
|
<button onClick={() => handleChat(chatInput)}>Send</button>
|
||||||
}
|
|
||||||
{
|
|
||||||
gameState.Hand &&
|
|
||||||
<Hand hand={gameState.Hand} actionOnClick={handleCardSend}/>
|
|
||||||
}
|
|
||||||
<ul>
|
<ul>
|
||||||
{
|
{chatMessages.map((message, index) => (
|
||||||
gameState.Players.map((player, index) => {
|
<li key={index}>{message.PlayerName}: {message.Message}</li>
|
||||||
const isCurrentPlayer = player === gameState.CurrentPlayer;
|
))}
|
||||||
const isMe = player === gameState.PlayerName;
|
|
||||||
return <li key={index} style={{fontWeight: isCurrentPlayer ? 'bold' : 'normal'}}>
|
|
||||||
{player} {isMe && '(You)'}
|
|
||||||
</li>
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
|
|
||||||
const AUTH_URL = `http://${process.env.REACT_APP_API_URL}/auth`;
|
|
||||||
|
|
||||||
interface IAuthContext {
|
|
||||||
sessionToken: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const AuthContext = React.createContext<IAuthContext>({
|
|
||||||
sessionToken: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
export const useAuth = () => React.useContext(AuthContext);
|
|
||||||
|
|
||||||
const AuthContextProvider = ({children}: any) => {
|
|
||||||
const [sessionToken] = React.useState('');
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const token = window.localStorage.getItem('session_token');
|
|
||||||
if (!token) {
|
|
||||||
fetch(AUTH_URL, {
|
|
||||||
method: 'GET'
|
|
||||||
}).then(res => res.json()).then(token => {
|
|
||||||
window.localStorage.setItem('session_token', token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AuthContext.Provider value={{sessionToken}}>
|
|
||||||
{children}
|
|
||||||
</AuthContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AuthContextProvider;
|
|
||||||
Reference in New Issue
Block a user