1
0
James Ketrenos 4ff9ad015e Added Activity feed
Fixed some more WebSocket timeouts

Changed Resource to support a label=true mode which puts a bubble lable instead of creating a stack

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
2022-03-01 20:19:48 -08:00

143 lines
4.5 KiB
JavaScript

import React, { useState, useEffect } from "react";
import "./Chat.css";
import PlayerColor from './PlayerColor.js';
import Paper from '@material-ui/core/Paper';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import Moment from 'react-moment';
import TextField from '@material-ui/core/TextField';
import Resource from './Resource.js';
import Dice from './Dice.js';
const Chat = ({ table }) => {
const [lastTop, setLastTop] = useState(0),
[autoScroll, setAutoscroll] = useState(true),
[latest, setLatest] = useState(''),
[scrollTime, setScrollTime] = useState(0);
const chatInput = (event) => {
};
const chatKeyPress = (event) => {
if (event.key === "Enter") {
if (!autoScroll) {
setAutoscroll(true);
}
table.sendChat(event.target.value);
event.target.value = "";
}
};
const chatScroll = (event) => {
const chatList = event.target,
fromBottom = Math.round(Math.abs((chatList.scrollHeight - chatList.offsetHeight) - chatList.scrollTop));
/* If scroll is within 20 pixels of the bottom, turn on auto-scroll */
const shouldAutoscroll = (fromBottom < 20);
if (shouldAutoscroll !== autoScroll) {
setAutoscroll(shouldAutoscroll);
}
/* If the list should not auto scroll, then cache the current
* top of the list and record when we did this so we honor
* the auto-scroll for at least 500ms */
if (!shouldAutoscroll) {
const target = Math.round(chatList.scrollTop);
if (target !== lastTop) {
setLastTop(target);
setScrollTime(Date.now());
}
}
};
useEffect(() => {
const chatList = document.getElementById("ChatList"),
currentTop = Math.round(chatList.scrollTop);
if (autoScroll) {
/* Auto-scroll to the bottom of the chat window */
const target = Math.round(chatList.scrollHeight - chatList.offsetHeight);
if (currentTop !== target) {
chatList.scrollTop = target;
}
return;
}
/* Maintain current position in scrolled view if the user hasn't
* been scrolling in the past 0.5s */
if ((Date.now() - scrollTime) > 500 && currentTop !== lastTop) {
chatList.scrollTop = lastTop;
}
});
//const timeDelta = game.timestamp - Date.now();
if (!table.game) {
console.log("Why no game?");
}
const messages = table.game && table.game.chat.map((item, index) => {
let message;
/* If the date is in the future, set it to now */
const dice = item.message.match(/^(.*rolled )([1-6])(, ([1-6]))?(.*)$/);
if (dice) {
if (dice[4]) {
message = <>{dice[1]}<Dice pips={dice[2]}/>, <Dice pips={dice[4]}/>{dice[5]}</>;
} else {
message = <>{dice[1]}<Dice pips={dice[2]}/>{dice[5]}</>;
}
} else {
let start = item.message;
while (start) {
const resource = start.match(/^(.*)(([0-9]+) (wood|sheep|wheat|stone|brick),?)(.*)$/);
if (resource) {
const count = resource[3] ? parseInt(resource[3]) : 1;
message = <><Resource label={true} count={count} type={resource[4]}/>{resource[5]}{message}</>;
start = resource[1];
} else {
message = <>{start}{message}</>;
start = '';
}
}
}
return (
<ListItem key={`msg-${item.date}`} className={item.color ? '' : 'System'}>
{ item.color &&
<PlayerColor color={item.color}/>
}
<ListItemText primary={message}
secondary={item.color && <Moment fromNow date={item.date > Date.now() ?
Date.now() : item.date} interval={1000}/>} />
</ListItem>
);
});
if (table.game && table.game.chat &&
table.game.chat.length &&
table.game.chat[table.game.chat.length - 1].date !== latest) {
setLatest(table.game.chat[table.game.chat.length - 1].date);
setAutoscroll(true);
}
const name = table.game ? table.game.name : "Why no game?";
const elapsed = table.game ? (table.game.timestamp - table.game.startTime) : undefined;
return (
<Paper className="Chat">
<List className="ChatList" id="ChatList" onScroll={chatScroll}>
{ messages }
</List>
<TextField className="ChatInput"
disabled={!name}
onChange={chatInput}
onKeyPress={chatKeyPress}
label={elapsed && <Moment tz={"Etc/GMT"} format="h:mm:ss" durationFromNow interval={1000} date={table.game.startTime}></Moment>} variant="outlined"/>
</Paper>
);
}
export default Chat;