Files
chemmazz/client/src/pages/PlayRoomPage.tsx

220 lines
11 KiB
TypeScript
Raw Normal View History

2021-01-29 15:52:45 +01:00
import { useCallback, useContext, useEffect, useState } from 'react';
import { Badge, Layout, Row, Col, Space, Typography, Button, message, Statistic } from 'antd';
import { PauseCircleOutlined, PlaySquareOutlined } from '@ant-design/icons';
import { FullScreen, useFullScreenHandle } from "react-full-screen";
import { useLocation } from 'wouter';
import { GameContext } from '../context/store';
import { StashManagementProvider } from '../context/stashManagementContext';
import StashManagementDrawer from '../components/StashManagementDrawer';
import Player from '../components/Player';
import Hand from '../components/Hand';
import Prompt from '../components/Prompt';
const { Content } = Layout;
const { Title } = Typography;
const PlayRoomPage = ({ params }) => {
const roomId = params.roomId;
const { state, dispatch } = useContext(GameContext);
const [, setLocation] = useLocation();
const fullScreenHandle = useFullScreenHandle();
const [isRoomOwner, setIsRoomOwner] = useState(false);
const [thisPlayerHand, setThisPlayerHand] = useState([]);
const [thisPlayerPrompt, setThisPlayerPrompt] = useState([]);
const [thisPlayerScore, setThisPlayerScore] = useState();
useEffect(() => {
console.log('Room id:', roomId);
console.log('Global state:', state);
console.log('Current user:', state.session?.display_name, state.session?.user_id);
const joinRoom = async () => {
if (state.room === null) {
console.log('Room not joined yet:', state.gameState.user_id, state.gameState.display_name);
try {
const room = await state.client.joinById(roomId, {
user_id: state.session?.user_id,
display_name: state.session?.display_name
});
dispatch({ type: 'JOIN_ROOM', payload: room });
} catch (error) {
message.error('Stanza non tovata');
setLocation('/');
}
} else {
console.log('Registering room handlers');
state.room.onStateChange((newState) => {
console.log('Room state changed:', newState);
dispatch({ type: 'GAME_STATE', payload: { ...newState } });
const isOwner = newState.roomOwner === state.session?.user_id;
setIsRoomOwner(isOwner);
});
state.room.onMessage('notification', (msg) => {
console.log('Message received from server:', msg);
const msg_type = msg.type || 'info';
message[msg_type](msg.text);
});
}
};
joinRoom();
return () => {
if (state.room) {
console.log('Removing room listeners...');
state.room.removeAllListeners();
dispatch({ type: 'LEAVE_ROOM' });
}
}
}, [state.room]);
useEffect(() => {
if (state.room === null) return;
// Setting the current player reference
const p = state.gameState.players.get(state.room.sessionId);
if (p !== undefined) {
console.log('Setting current player hand:', p, p.hand);
setThisPlayerHand(p.hand);
setThisPlayerPrompt(p.prompt);
setThisPlayerScore(p.score);
}
}, [state.room, state.gameState]);
const handleStartGame = useCallback(() => {
state.room.send('admin', { command: 'start-game' });
}, [state.room]);
const handlePauseGame = useCallback(() => {
state.room.send('admin', { command: 'pause-game' });
}, [state.room]);
const handleResumeGame = useCallback(() => {
state.room.send('resume-game', {});
}, [state.room]);
return (
<FullScreen handle={fullScreenHandle}>
<StashManagementProvider>
<Layout className='play-room'>
<Content>
<Row justify="center">
<Col flex="auto" className={`main-scene bg-${state.gameState.bg}`}>
{isRoomOwner && (
<Space className="admin-commands">
{!state.gameState.running && (
<Button icon={<PlaySquareOutlined />} type="link" size="large" onClick={handleStartGame} />
)}
{(state.gameState.running && state.gameState.paused) && (
<Button icon={<PlaySquareOutlined />} type="link" size="large" onClick={handleResumeGame} />
)}
{(state.gameState.running && !state.gameState.paused) && (
<Button icon={<PauseCircleOutlined />} type="link" size="large" onClick={handlePauseGame} />
)}
</Space>
)}
{(state.gameState.running && !state.gameState.paused) && (
<Space direction="vertical" align="center" style={{ width: '100%' }} size="large">
<Statistic title="Piatto" value={state.gameState.pot} />
<Space direction="horizontal" align="baseline" split="VS" size="large" className="the-ring">
<div className="player">
<div className="picture" id="player">
<div className="badges">
<Player player={state.gameState.player1} displayAdminMenu={false} />
<div className="lives">
<i className="fas fa-heart" title="1 Vita"></i>
<i className="fas fa-heart" title="1 Vita"></i>
<i className="fas fa-heart" title="1 Vita"></i>
</div>
<div className="status"></div>
</div>
</div>
<div className="name">
{state.gameState.player1.displayName} (Banco)
{(state.gameState.player1.prompt && state.gameState.player1.prompt.visible) && (<Badge status="processing" />)}
</div>
<Hand cards={state.gameState.player1.hand} showHole={false} />
</div>
<div className="player">
<div className="picture" id="player">
<Player player={state.gameState.player2} displayAdminMenu={false} />
<div className="badges">
<div className="lives">
<i className="fas fa-heart" title="1 Vita"></i>
<i className="fas fa-heart" title="1 Vita"></i>
<i className="fas fa-heart" title="1 Vita"></i>
</div>
<div className="status"></div>
</div>
</div>
<div className="name">
{state.gameState.player2.displayName}
{(state.gameState.player2.prompt && state.gameState.player2.prompt.visible) && (<Badge status="processing" />)}
</div>
<Hand cards={state.gameState.player2.hand} showHole={false} />
<Statistic title="Scommessa" value={state.gameState.currentBet} />
</div>
</Space>
</Space>
)}
</Col>
<Col className="players" xs={4} md={6} lg={8} xl={10}>
<Title level={4}>In gioco</Title>
<Space size={12} wrap>
{Array.from<any>(state.gameState.players.values()).filter((player, index) => {
return player.playing;
}).map((player, index) => (
<Player key={index} player={player} displayAdminMenu={isRoomOwner} />
))}
</Space>
<Title level={4}>Spettatori</Title>
<Space size={12} wrap>
{Array.from<any>(state.gameState.players.values()).filter((player, index) => {
return !player.playing;
}).map((player, index) => (
<Player key={index} player={player} displayAdminMenu={isRoomOwner} />
))}
</Space>
</Col>
</Row>
<Row>
<Col className="game-controls" span={24}>
<Space direction="vertical" style={{ width: "100%" }}>
{/* <Button onClick={fullScreenHandle.enter}>Full screen</Button> */}
<Row>
<Col flex={2}>
<Hand cards={thisPlayerHand} showHole={true} />
</Col>
<Col flex={2}>
<Space direction="vertical">
{thisPlayerHand.length > 0 && <Statistic title="Il tuo punteggio:" value={thisPlayerScore} />}
<Prompt prompt={thisPlayerPrompt} />
</Space>
</Col>
</Row>
</Space>
</Col>
</Row>
<StashManagementDrawer />
</Content>
</Layout>
</StashManagementProvider>
</FullScreen >
);
}
export default PlayRoomPage;