1
0
Signed-off-by: James Ketrenos <james.p.ketrenos@intel.com>
This commit is contained in:
James Ketrenos 2020-04-25 13:16:22 -07:00
parent 0170f99c79
commit e6e5dfc6ea
4 changed files with 105 additions and 39 deletions

View File

@ -103,10 +103,7 @@ router.get("/:id", (req, res/*, next*/) => {
console.log("GET games/" + req.params.id); console.log("GET games/" + req.params.id);
if (req.params.id in games) { if (req.params.id in games) {
const game = games[req.params.id]; const game = games[req.params.id];
return res.status(200).send(Object.assign({}, game, { return sendGame(res, req, game)
timestamp: Date.now(),
activePlayer: req.session.activePlayer
}));
} else { } else {
const error = `Game not found: ${req.params.id}`; const error = `Game not found: ${req.params.id}`;
return res.status(404).send(error); return res.status(404).send(error);
@ -119,6 +116,7 @@ router.put("/:id", (req, res/*, next*/) => {
const game = games[req.params.id], const game = games[req.params.id],
changes = req.body; changes = req.body;
console.log(req.session.id, req.session.activePlayer);
console.log(JSON.stringify(changes, null, 2)); console.log(JSON.stringify(changes, null, 2));
for (let change in changes) { for (let change in changes) {
@ -152,16 +150,21 @@ router.put("/:id", (req, res/*, next*/) => {
break; break;
} }
} }
return res.status(200).send(Object.assign({}, game, { return sendGame(res, req, game);
timestamp: Date.now(),
activePlayer: req.session.activePlayer
}));
} else { } else {
const error = `Game not found: ${req.params.id}`; const error = `Game not found: ${req.params.id}`;
return res.status(404).send(error); return res.status(404).send(error);
} }
}); });
const sendGame = (res, req, game) => {
return res.status(200).send(Object.assign({}, game, {
timestamp: Date.now(),
activePlayer: (req.session && req.session.activePlayer) ?
req.session.activePlayer : null
}));
}
router.post("/", (req, res/*, next*/) => { router.post("/", (req, res/*, next*/) => {
console.log("POST games/"); console.log("POST games/");
const game = { const game = {
@ -186,8 +189,8 @@ router.post("/", (req, res/*, next*/) => {
wheat: 19, wheat: 19,
longestRoad: null, longestRoad: null,
largestArmy: null, largestArmy: null,
chat: [ { from: "R", date: Date.now(), message: "Hello, world!" } ], chat: [ { from: "R", date: Date.now(), message: "Server initialized!" } ],
id: crypto.randomBytes(20).toString('hex') id: crypto.randomBytes(8).toString('hex')
}; };
[ "tiles", "pips", "borders" ].forEach((field) => { [ "tiles", "pips", "borders" ].forEach((field) => {
@ -208,10 +211,7 @@ router.post("/", (req, res/*, next*/) => {
games[game.id] = game; games[game.id] = game;
console.log(`New game created: ${game.id}`); console.log(`New game created: ${game.id}`);
return res.status(200).send(Object.assign({}, game, { return sendGame(res, req, game);
timestamp: Date.now(),
activePlayer: req.session.activePlayer
}));
}); });

Binary file not shown.

View File

@ -42,11 +42,21 @@
filter: brightness(150%); filter: brightness(150%);
} }
.Game {
display: inline-flex;
flex-direction: column;
width: 20em;
opacity: 0.7;
z-index: 100;
overflow: hidden;
}
.Game > *:not(:last-child) {
margin-bottom: 0.5em;
}
.Chat { .Chat {
padding: 0.5em; padding: 0.5em;
width: 30vmax;
display: inline-block;
opacity: 0.7;
} }
.Chat > * { .Chat > * {
@ -54,15 +64,12 @@
} }
.Chat > :first-child { .Chat > :first-child {
height: 10vh; max-height: 30vh;
overflow-y: scroll; overflow-y: scroll;
} }
.Players { .Players {
padding: 0.5em; padding: 0.5em;
width: 30vmax;
display: inline-block;
opacity: 0.7;
} }
#ChatList { #ChatList {

View File

@ -210,13 +210,17 @@ class Resource extends React.Component {
const Chat = ({ game, promoteGameState }) => { const Chat = ({ game, promoteGameState }) => {
const chatInput = (event) => { const chatInput = (event) => {
console.log(event.target.value);
}; };
const chatKeyPress = (event) => { const chatKeyPress = (event) => {
if (event.key == "Enter") { if (event.key == "Enter") {
console.log(`Send: ${event.target.value}`); console.log(`Send: ${event.target.value}`);
promoteGameState({ chat: { player: game.activePlayer, message: event.target.value }}); promoteGameState({
chat: {
player: game.activePlayer,
message: event.target.value
}
});
event.target.value = ""; event.target.value = "";
} }
}; };
@ -227,7 +231,6 @@ const Chat = ({ game, promoteGameState }) => {
const chatList = document.getElementById("ChatList"); const chatList = document.getElementById("ChatList");
chatList.scrollTop = chatList.scrollHeight - chatList.offsetHeight; chatList.scrollTop = chatList.scrollHeight - chatList.offsetHeight;
}) })
console.log(JSON.stringify(game, null, 2));
const timeDelta = game.timestamp - Date.now(); const timeDelta = game.timestamp - Date.now();
@ -243,6 +246,10 @@ const Chat = ({ game, promoteGameState }) => {
); );
}); });
useEffect(() => {
document.querySelector(".chatInput").focus();
});
return ( return (
<Paper className="Chat"> <Paper className="Chat">
<List id="ChatList"> <List id="ChatList">
@ -250,6 +257,7 @@ const Chat = ({ game, promoteGameState }) => {
</List> </List>
<TextField className="chatInput" <TextField className="chatInput"
disabled={!game.activePlayer} disabled={!game.activePlayer}
inputRef={input => input && input.focus()}
onChange={chatInput} onChange={chatInput}
onKeyPress={chatKeyPress} onKeyPress={chatKeyPress}
label={(<Moment format="h:mm:ss" interval={1000}/>)} variant="outlined"/> label={(<Moment format="h:mm:ss" interval={1000}/>)} variant="outlined"/>
@ -278,25 +286,27 @@ const Players = ({ game, promoteGameState }) => {
const change = { players: {} }; const change = { players: {} };
/* Joining: selected != "", activePlayer == "", and name != "" */ /* Joining: selected != "", activePlayer == "", and name != "" */
if (selected && !game.activePlayer && name != "") { if (selected && !game.activePlayer && name) {
change.players[selected] = { name: name } change.players[selected] = { name: name }
promoteGameState(change) promoteGameState(change)
return; return;
} }
/* Leaving: selected = "", name = "", activePlayer != "" */ /* Leaving: selected = "", name = "", activePlayer != "" */
if (!selected && game.activePlayer != "") { if (!selected && game.activePlayer) {
change.players[game.activePlayer] = { name: "" } change.players[game.activePlayer] = { name: "" }
promoteGameState(change) promoteGameState(change)
return;
} }
/* Updating name: selected != "", activePlayer != "", name != "", name != activePlayer.name*/ /* Updating name: selected != "", activePlayer != "", name != "", name != activePlayer.name*/
if (selected != "" && if (selected &&
game.activePlayer != "" && game.activePlayer &&
name != "" && name &&
game.players[game.activePlayer].name != name) { game.players[game.activePlayer].name != name) {
change.players[game.activePlayer] = { name: name } change.players[game.activePlayer] = { name: name }
promoteGameState(change) promoteGameState(change)
return;
} }
}); });
@ -325,7 +335,7 @@ const Players = ({ game, promoteGameState }) => {
onChange={nameInput} onChange={nameInput}
onKeyPress={nameKeyPress} onKeyPress={nameKeyPress}
inputRef={input => input && input.focus()} inputRef={input => input && input.focus()}
disabled={name != item.name} disabled={(name != item.name) ? true: false}
label="Name" label="Name"
variant="outlined" autoFocus/> variant="outlined" autoFocus/>
} }
@ -334,7 +344,7 @@ const Players = ({ game, promoteGameState }) => {
} }
</> </>
<Switch edge="end" <Switch edge="end"
disabled={selected && selected != key} checked={selected == key} disabled={(selected && selected != key) ? true : false} checked={selected == key}
onChange={() => toggleSelected(key)}/> onChange={() => toggleSelected(key)}/>
</ListItem> </ListItem>
)); ));
@ -372,10 +382,13 @@ class Board extends React.Component {
this.randomize = this.randomize.bind(this); this.randomize = this.randomize.bind(this);
this.throwDice = this.throwDice.bind(this); this.throwDice = this.throwDice.bind(this);
this.promoteGameState = this.promoteGameState.bind(this); this.promoteGameState = this.promoteGameState.bind(this);
this.loadGame = this.loadGame.bind(this);
this.mouse = { x: 0, y: 0 }; this.mouse = { x: 0, y: 0 };
this.radius = 0.317; this.radius = 0.317;
this.loadTimer = null;
this.game = null; this.game = null;
this.pips = []; this.pips = [];
this.tiles = []; this.tiles = [];
@ -433,15 +446,56 @@ class Board extends React.Component {
this.borders = this.game.borders.map((file) => { this.borders = this.game.borders.map((file) => {
return Border(this, file); return Border(this, file);
}); });
this.loadTimer = window.setTimeout(this.loadGame, 1000);
}).catch((error) => { }).catch((error) => {
console.error(error); console.error(error);
alert(error); alert(error);
})
}
loadGame() {
if (this.loadTimer) {
window.clearTimeout(this.loadTimer);
this.loadTimer = null;
}
if (!this.state.game) {
return;
}
window.fetch(`api/v1/games/${this.state.game.id}`, {
method: "GET",
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
}
}).then((res) => {
if (res.status > 400) {
console.log(res);
throw `Unable to load state`;
}
return res.json();
}).then((game) => {
console.log (`Game state loaded.`);
this.setState({ game: game });
}).catch((error) => {
console.error(error);
alert(error);
}).then(() => {
this.loadTimer = window.setTimeout(this.loadGame, 1000);
}); });
} }
promoteGameState(change) { promoteGameState(change) {
console.log("Requesting state change: ", change); console.log("Requesting state change: ", change);
if (this.loadTimer) {
window.clearTimeout(this.loadTimer);
this.loadTimer = null;
}
window.fetch(`api/v1/games/${this.state.game.id}`, { window.fetch(`api/v1/games/${this.state.game.id}`, {
method: "PUT", method: "PUT",
cache: 'no-cache', cache: 'no-cache',
@ -453,14 +507,19 @@ class Board extends React.Component {
}).then((res) => { }).then((res) => {
if (res.status > 400) { if (res.status > 400) {
console.error(res); console.error(res);
alert(`Unable to change state`); throw `Unable to change state`;
} }
return res.json(); return res.json();
}).then((game) => { }).then((game) => {
console.log (`Game state changed.`); console.log (`Game state changed.`);
this.setState({ game: game }); this.setState({ game: game });
}).catch((error) => {
console.error(error);
alert(error);
}).then(() => {
this.loadTimer = window.setTimeout(this.loadGame, 1000);
}); });
} }
randomize() { randomize() {
//this.borders = shuffle(this.borders); //this.borders = shuffle(this.borders);
@ -1013,10 +1072,10 @@ class Board extends React.Component {
<canvas className="Display" ref={el => this.canvas = el}></canvas> <canvas className="Display" ref={el => this.canvas = el}></canvas>
<div className="Cards" ref={el => this.cards = el}> <div className="Cards" ref={el => this.cards = el}>
{ game && { game &&
<> <div className="Game">
<Chat game={game} promoteGameState={this.promoteGameState}/>
<Players game={game} promoteGameState={this.promoteGameState}/> <Players game={game} promoteGameState={this.promoteGameState}/>
</> <Chat game={game} promoteGameState={this.promoteGameState}/>
</div>
} }
<div>In hand</div> <div>In hand</div>
<div className="Hand"> <div className="Hand">