commit 0ca87da278c7abe78c68f1cf2b354365b695f65d (patch)
parent dd8eacbbc87ff296669cfb98aa30edd271122aea
Author: Chris Karle <chriskarle@hotmail.com>
Date: Fri, 22 May 2020 01:41:30 -0400
CardTable, ChatPanel
Implement chat functionality by building out ChatPanel.
Fix the known margin problems introduced by refactoring layout to
two, side-by-side Grid comps... likely be one or two more
discovered in play testing.
Diffstat:
3 files changed, 177 insertions(+), 12 deletions(-)
diff --git a/assets/app.scss b/assets/app.scss
@@ -36,10 +36,13 @@
}
.table__main {
- margin-top: 2rem;
+ // margin-top: 2rem;
min-width: 950px;
min-height: 650px;
}
+.banner {
+ padding-top: 1rem;
+}
.og {
padding-left: 0;
@@ -52,6 +55,7 @@
display: flex;
flex-direction: column;
align-items: flex-end;
+ padding-top: 1rem;
}
.exit__row {
@@ -62,6 +66,10 @@
.leave__button {
font-size: 1.3rem;
}
+.menu__holder {
+ padding-top: 1rem;
+ padding-left: 2rem;
+}
.seat__picker {
height: 46vh;
margin-top: 2vh;
@@ -110,6 +118,7 @@
display: flex;
flex-direction: column;
align-items: center;
+ padding-top: 1rem;
}
.partner__info {
width: 100%;
@@ -145,8 +154,27 @@
// background-color: cadetblue;
}
-.chat__tile {
+.chat__panel {
width: 100%;
+ display: flex;
+ flex-direction: column;
+ border: 1px solid;
+}
+.chat__holder {
+ flex: auto;
+ max-height: 207px;
+}
+.chat__tile {
+ height: 100%;
+ overflow: auto;
+ background-color: whitesmoke;
+}
+.chat__input__row {
+ display: flex;
+}
+.chat__post {
+ padding-right: 0.3rem;
+ padding-left: 0.3rem;
}
.hid__card {
width: 30px;
@@ -272,6 +300,7 @@
}
.table__bot {
height: 20vh;
+ margin-left: 0;
}
.tt__right {
height: 20vh;
@@ -282,11 +311,10 @@
height: 35vh;
// background-color: lightsalmon;
}
+.tb__left {
+ padding-left: 2rem;
+}
-
-// .tb__left {
-// background-color: slategray;
-// }
// .hd__left {
// background-color: rosybrown;
// }
diff --git a/assets/components/CardTable.js b/assets/components/CardTable.js
@@ -1,12 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
-import {Button, Grid, Row, Column, OverflowMenu, OverflowMenuItem, Tile} from 'carbon-components-react';
+import {Button, Grid, Row, Column, OverflowMenu, OverflowMenuItem} from 'carbon-components-react';
import {Logout32, Redo32, Package32} from '@carbon/icons-react';
import SeatPicker from './SeatPicker';
import MainHand from './MainHand';
import HiddenHand from './HiddenHand';
import TrumpPicker from './TrumpPicker';
+import ChatPanel from './ChatPanel';
const trumpPlacement = ['me', 'left', 'partner', 'right'];
const suit = {
@@ -56,7 +57,8 @@ export default class CardTable extends React.Component {
innerWinMsg: '',
onlyAlone: false,
noPick: false,
- amSpectator: false
+ amSpectator: false,
+ latestPost: ''
};
};
@@ -95,9 +97,20 @@ export default class CardTable extends React.Component {
} else {
this.processLobby(msg);
}
- };
+ } else if ('chat' == msg.msg_type) {
+ this.processChat(msg);
+ }
};
+ processChat = msg => {
+ let post = msg.msg;
+ if (post && post != '') {
+ this.setState({
+ latestPost: post
+ });
+ }
+ }
+
processResponseSwitch = msg => {
switch (msg.game.phase) {
case 'lobby':
@@ -518,6 +531,16 @@ export default class CardTable extends React.Component {
}));
}
+ sendChat = post => {
+ console.log(post);
+ if (post && post != ''){
+ this.props.client.send(JSON.stringify({
+ action: 'chat',
+ msg: post
+ }));
+ }
+ }
+
genGameOver = () => {
const {innerWinMsg, amSpectator} = this.state;
let retVal = [];
@@ -644,7 +667,7 @@ export default class CardTable extends React.Component {
const { playerNames, mySeat, phase, myCards, myTurnInfo, amSpectator,
partnerHandInfo, partnerTurnInfo, partnerSeat, leftTurnInfo, leftHandInfo, leftSeat,
rightHandInfo, rightTurnInfo, rightSeat, trumpPlace, trumpNom, turnSeat,
- dealSeat, trump, handLengths, score, trickWinner, bannerMsg, noPick, onlyAlone } = this.state;
+ dealSeat, trump, handLengths, score, trickWinner, bannerMsg, noPick, onlyAlone, latestPost } = this.state;
const showSeatPicker = phase == 'lobby';
const showGameOver = phase == 'end';
const showTrump = (phase == 'vote') || (phase == 'vote2') || (phase == 'swap');
@@ -666,7 +689,7 @@ export default class CardTable extends React.Component {
<Grid className="inner__left">
{(showSeatPicker || showGameOver) && (
<Row className="table__header">
- <h3>{bannerMsg}</h3>
+ <h3 className="banner">{bannerMsg}</h3>
</Row>
)}
<Row className="table__top">
@@ -807,7 +830,9 @@ export default class CardTable extends React.Component {
</div>)}
</Row>
<Row className="tb__right">
- <Tile className="chat__tile">Coming Soon! future chat area here</Tile>
+ <ChatPanel
+ receivedChat={latestPost}
+ sendChat={this.sendChat} />
</Row>
</Grid>
</Column>
diff --git a/assets/components/ChatPanel.js b/assets/components/ChatPanel.js
@@ -0,0 +1,111 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { Tile, TextInput, Button } from 'carbon-components-react';
+import {SendFilled16} from '@carbon/icons-react';
+
+const MAX_POSTS = 40;
+
+class ChatPanel extends React.Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ post: '',
+ numPosts: 0,
+ postArray: []
+ }
+ };
+
+ componentDidUpdate (prevProps) {
+ const { receivedChat } = this.props;
+ const { postArray, numPosts } = this.state;
+ let nextArray = postArray;
+ if (receivedChat && (receivedChat != prevProps.receivedChat)){
+ const nextNum = numPosts + 1;
+ const id = 'post-' + nextNum;
+ nextArray.push(
+ <p className="chat__post"
+ key={nextNum}
+ id={id}>{receivedChat}</p>
+ );
+ if (nextArray.length > MAX_POSTS){
+ nextArray = nextArray.slice(1);
+ }
+ this.setState({
+ postArray: nextArray,
+ numPosts: nextNum
+ }, () => {
+ const element = document.getElementById(id);
+ if (element) {
+ console.log(element);
+ setTimeout(()=>{
+ element.scrollIntoView();
+ }, 100);
+ }
+ });
+ // document.getElementById("chat__tile").scrollIntoView(false);
+ // if (this.chatTile) {
+ // console.log(this.chatTile);
+ // this.chatTile.scrollIntoView(false);
+ // }
+ }
+ }
+
+ handleChatIn = event => {
+ const val = event.target.value;
+ console.log(val);
+ this.setState({ post: val});
+ }
+
+ handleSendPost = () => {
+ const { post } = this.state;
+ if (post && post != ''){
+ this.props.sendChat(post);
+ }
+ this.setState({
+ post: ''
+ });
+ this.chatIn.value = '';
+ this.postButton.blur();
+ }
+
+ render () {
+ const { post, postArray } = this.state;
+ return (
+ <div className="chat__panel">
+ <div className="chat__holder">
+ <div className="chat__tile">
+ {postArray}
+ </div>
+ </div>
+ <div className="chat__input__row">
+ <TextInput
+ id="chat__in"
+ light
+ className="chat__in__input"
+ placeholder="enter chat posts here"
+ size="sm"
+ onChange={this.handleChatIn}
+ ref={(input) => {this.chatIn = input;}}
+ />
+ <Button
+ className="post__button"
+ size="small"
+ hasIconOnly={true}
+ onClick={this.handleSendPost}
+ renderIcon={SendFilled16}
+ iconDescription="send chat"
+ tooltipPosition="bottom"
+ ref={(button) => {this.postButton = button;}}
+ />
+ </div>
+ </div>
+ )
+ }
+
+}
+ChatPanel.propTypes = {
+ receivedChat: PropTypes.string,
+ sendChat: PropTypes.func
+}
+export default ChatPanel;
+\ No newline at end of file