diff --git a/client/src/Board.css b/client/src/Board.css
index 5d4c628..289e58e 100755
--- a/client/src/Board.css
+++ b/client/src/Board.css
@@ -108,6 +108,30 @@
scroll-behavior: smooth;
}
+#ChatList .MuiListItem-gutters {
+ padding: 2px 0 2px 0;
+}
+
+#ChatList .MuiTypography-body1 {
+ font-size: 0.8rem;
+}
+
+#ChatList .MuiTypography-body2 {
+ font-size: 0.7rem;
+}
+
+#ChatList .MuiListItemText-multiline {
+ margin-top: 0;
+ margin-bottom: 0;
+ padding: 4px 0px 4px 4px;
+}
+
+#ChatList .PlayerColor {
+ width: 1em;
+ height: 1em;
+ padding: 0px;
+}
+
.Players {
padding: 0.5em;
user-select: none;
@@ -123,6 +147,10 @@
cursor: pointer;
}
+.Players .PlayerSelector[data-selected=true] {
+ background-color: rgba(255,255,255,0.5);
+}
+
.Players .PlayerToggle {
min-width: 5em;
display: inline-flex;
@@ -229,13 +257,13 @@ button {
user-select: none;
}
-.Message div {
- display: inline-flex;
+.Message .PlayerColor {
+ width: 1em;
+ height: 1em;
}
-.Message .PlayerColor {
- position: relative;
- top: -0.25em;
+.Message div {
+ display: inline-flex;
}
.PlayerName {
diff --git a/client/src/Board.js b/client/src/Board.js
index 750c15b..614e732 100755
--- a/client/src/Board.js
+++ b/client/src/Board.js
@@ -6,12 +6,11 @@ import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
+import ListItemAvatar from '@material-ui/core/ListItemAvatar';
import ListItemText from '@material-ui/core/ListItemText';
-import ListItemAvatar from '@material-ui/core/ListItemAvatar';
import { makeStyles } from '@material-ui/core/styles';
import { deepOrange, lightBlue, red, grey } from '@material-ui/core/colors';
import Avatar from '@material-ui/core/Avatar';
-import Switch from '@material-ui/core/Switch';
import Moment from 'react-moment';
//import moment from 'moment';
@@ -72,16 +71,9 @@ const useStyles = makeStyles((theme) => ({
}));
const PlayerColor = ({ color }) => {
- const colors = getPlayerColors(color)
+ const classes = useStyles();
return (
-
+
);
};
@@ -293,8 +285,6 @@ const Chat = ({ board, promoteGameState }) => {
}
};
- const classes = useStyles();
-
useEffect(() => {
const chatList = document.getElementById("ChatList"),
currentTop = Math.round(chatList.scrollTop);
@@ -318,13 +308,10 @@ const Chat = ({ board, promoteGameState }) => {
//const timeDelta = game.timestamp - Date.now();
const messages = board.game.chat.map((item, index) => {
/* If the date is in the future, set it to now */
- item.date = item.date > Date.now() ? Date.now() : item.date;
return (
-
-
- {item.from}
-
- )} />
+
+
+ Date.now() ? Date.now() : item.date} interval={1000}/>)} />
);
});
@@ -436,8 +423,6 @@ const Players = ({ board }) => {
board.setSelected(board.game.color === key ? "" : key);
}
- const classes = useStyles();
-
const players = [];
for (let color in board.game.players) {
const item = board.game.players[color];
@@ -445,35 +430,22 @@ const Players = ({ board }) => {
continue;
}
const name = getPlayerName(board.game.sessions, color),
- selectable = item.status === 'Not active' || board.game.color === color;
- item.lastActive = item.lastActive > Date.now() ? Date.now() : item.lastActive;
- let toggleText;
- if (selectable) {
- if (board.game.state !== 'lobby') {
- toggleText = 'Exit to lobby.';
- } else {
- toggleText = item.status === 'Not active'
- ? Play as {board.game.color ? ' instead' : ''}.
- : Stop playing as .;
- }
- }
+ selectable = board.game.state === 'lobby' && (item.status === 'Not active' || board.game.color === color);
+ let toggleText = name ? name : "Available";
players.push((
{ selectable && toggleSelected(color) }} className="PlayerSelector" key={`player-${color}`}>
-
- {color}
-
-
- { item.status + ' ' }
- { item.status !== 'Not active' && }
- >)} />
- { selectable &&
-
-
- {toggleText}
-
+ data-selectable={selectable}
+ data-selected={board.game.color === color}
+ className="PlayerSelector"
+ key={`player-${color}`}>
+ { selectable && toggleSelected(color) }} color={color}/>
+ { selectable && toggleSelected(color) }}primary={toggleText} secondary={(
+ <>
+ { item.status + ' ' }
+ { item.status !== 'Not active' && Date.now() ? Date.now() : item.lastActive}/>}
+ >)} />
+ { board.game.state !== 'lobby' && board.game.color === color &&
+
}
));
diff --git a/server/routes/games.js b/server/routes/games.js
index a917d5d..17ac1e9 100755
--- a/server/routes/games.js
+++ b/server/routes/games.js
@@ -501,6 +501,7 @@ const getActiveCount = (game) => {
const sendGame = async (req, res, game, error) => {
const active = getActiveCount(game);
+ /* Enforce game limit of >= 2 players */
if (active < 2 && game.state != 'lobby' && game.state != 'invalid') {
let message = "Insufficient players in game. Setting back to lobby."
game.chat.push({ date: Date.now(), message: message });
@@ -509,6 +510,7 @@ const sendGame = async (req, res, game, error) => {
}
game.active = active;
+ /* Update the session lastActive clock */
let session;
if (req.session) {
session = getSession(game, req.session);
@@ -522,6 +524,15 @@ const sendGame = async (req, res, game, error) => {
};
}
+ /* Ensure chat messages have a unique date: stamp as it is used as the index key */
+ let lastTime = 0;
+ if (game.chat) game.chat.forEach((message) => {
+ if (message.date <= lastTime) {
+ message.date = lastTime + 1;
+ }
+ lastTime = message.date;
+ });
+
/* Shallow copy game, filling its sessions with a shallow copy of sessions so we can then
* delete the player field from them */
const reducedGame = Object.assign({}, game, { sessions: {} }),