TableList.js (10186B) [raw]
1 import React from 'react'; 2 import PropTypes from 'prop-types'; 3 import { ClickableTile, Button, ModalWrapper, TextInput, Checkbox, ComposedModal, 4 ModalHeader, ModalBody, ModalFooter } from 'carbon-components-react'; 5 import {Renew16, Locked16} from '@carbon/icons-react'; 6 7 export default class TableList extends React.Component { 8 9 constructor(props) { 10 super(props); 11 this.state = { 12 pwdOpen: false, 13 joinInfo: null 14 }; 15 } 16 17 conflictHandler = (tableName) => { 18 const {playerName} = this.props; 19 alert('The "' + tableName + '" table already has a player named ' + playerName 20 + ' -- you must change your name to join this table, or choose another table.'); 21 } 22 23 handleJoin = (tableName, hasPwd) => { 24 console.log('handleJoin, hasPwd=', hasPwd); 25 const {playerName} = this.props; 26 let joinInfo = { 27 table: tableName, 28 player_name: playerName 29 }; 30 if (!hasPwd) { 31 this.props.joinTable(joinInfo); 32 } else { 33 this.setState({ 34 joinInfo: joinInfo, 35 pwdOpen: true 36 }) 37 } 38 } 39 40 handleCreate = () => { 41 const {playerName} = this.props; 42 console.log('handleCreate, optHpick:', this.optHpick.value); 43 const tableName = this.ctName.value; 44 if (!tableName || tableName == ''){ 45 alert('Unnamed tables are not permitted'); 46 } else { 47 const pwd = this.ctPwd.value; 48 let settings = {}; 49 settings.hard_order = this.optHorder.checked; 50 settings.hard_pick = this.optHpick.checked; 51 settings.stick_dealer = this.optStick.checked; 52 let joinInfo = { 53 table: tableName, 54 player_name: playerName, 55 settings: settings 56 } 57 if (pwd && pwd != ''){ 58 joinInfo.password = pwd; 59 } 60 this.props.joinTable(joinInfo); 61 } 62 } 63 64 handleRefresh = () => { 65 this.refreshButton.blur(); 66 this.props.refresh(); 67 }; 68 69 handleModalClose = () => { 70 console.log('modal close'); 71 this.pmPwd.value=''; 72 this.setState({ 73 pwdOpen: false 74 }); 75 }; 76 77 handleModalSave = () => { 78 const {joinInfo} = this.state; 79 const pwd = this.pmPwd.value; 80 console.log('modal save, pwd=', pwd); 81 joinInfo.password = pwd; 82 this.props.joinTable(joinInfo); 83 this.pmPwd.value=''; 84 this.setState({ 85 pwdOpen: false 86 }); 87 }; 88 89 renderCards = () => { 90 const {tables, playerName} = this.props; 91 let retVal = []; 92 if (tables){ 93 tables.forEach(table => { 94 const conflict = table.players.indexOf(playerName) > -1 95 || table.spectators.indexOf(playerName) > -1; 96 const conflictWarning = conflict ? 97 (<div className="table__conflict">A user named "{playerName}" is at this table</div>) : null; 98 const clickHandler = conflict ? this.conflictHandler : this.handleJoin; 99 let seated = ''; 100 for (let ni = 0; ni < 4; ni++) { 101 if (table.players[ni] != 'Empty'){ 102 if (seated != ''){ 103 seated += ', '; 104 } 105 seated += table.players[ni]; 106 } 107 } 108 let specs = ''; 109 table.spectators.forEach(spName => { 110 if (specs != ''){ 111 specs += ', '; 112 } 113 specs += spName; 114 }) 115 const lockIcon = table.has_password ? (<Locked16 fill="red" description="locked table"/>) : null; 116 const nameClass = table.has_password ? "table__name table__name--locked" : "table__name"; 117 const settings = table.settings; 118 let optionSpan = ''; 119 if (settings.hard_pick || settings.hard_order || settings.stick_dealer){ 120 const thp = settings.hard_pick ? 'HardPick' : ''; 121 const tho = settings.hard_order ? 'HardOrder' : ''; 122 const tsd = settings.stick_dealer ? 'StickDealer' : ''; 123 optionSpan = (<span className="table__options"> {thp} {tho} {tsd}</span>); 124 } 125 retVal.push( 126 <ClickableTile 127 key={table.name} 128 handleClick={() => clickHandler(table.name, table.has_password)} 129 > 130 <div className={nameClass}>{lockIcon}{table.name}{optionSpan}</div> 131 {conflictWarning} 132 <div className="table__players">Seated: {seated}</div> 133 <div className="table__spectators">Spectators: {specs}</div> 134 </ClickableTile> 135 ) 136 }); 137 } 138 if (retVal.length == 0) { 139 retVal = ( 140 <div className="tlist__none"> 141 No tables yet -- create one or refresh if expecting one... 142 </div> 143 ); 144 } 145 return retVal; 146 } 147 148 renderPasswordModal = () => { 149 const {pwdOpen} = this.state; 150 return ( 151 <ComposedModal 152 className="pm" 153 open={pwdOpen} 154 onClose={this.handleModalClose}> 155 <ModalHeader 156 className="pm__head" 157 title="Enter Table Password" 158 iconDescription="close" 159 // closeModal={this.handleModalClose} 160 /> 161 <ModalBody 162 className="pm__body" 163 > 164 <TextInput 165 id="pm__pwd" 166 placeholder="enter table password" 167 labelText="Password" 168 ref={(input) => {this.pmPwd = input;}} 169 /> 170 </ModalBody> 171 <ModalFooter 172 className="pm_foot" 173 primaryButtonText="Save" 174 // closeModal={this.handleModalClose} 175 onRequestSubmit={this.handleModalSave} 176 /> 177 </ComposedModal> 178 ); 179 } 180 181 render () { 182 const {tables} = this.props; 183 const showCards = tables.length > 0; 184 const cards = this.renderCards(); 185 const passwordModal = this.renderPasswordModal(); 186 return ( 187 <div className="tlist__outer"> 188 {passwordModal} 189 <div className="tlist__header"> 190 <div className="tlist__title__row"> 191 <div className="tlist__title">Click a table to join it... or</div> 192 <ModalWrapper 193 className="create__modal" 194 buttonTriggerText="Create a New Table" 195 primaryButtonText="Create" 196 modalHeading="New Table" 197 handleSubmit={this.handleCreate} 198 shouldCloseAfterSubmit={true} 199 > 200 <TextInput 201 id="ct__name" 202 placeholder="name your table" 203 labelText="Table Name" 204 ref={(input) => {this.ctName = input;}} 205 /> 206 <br/> 207 <TextInput 208 id="ct__pwd" 209 placeholder="leave blank for no password" 210 labelText="Table Password (optional)" 211 ref={(input) => {this.ctPwd = input;}} 212 /> 213 <br/> 214 <fieldset className="ct__optSet"> 215 <legend className="ct__optLabel">Game Options</legend> 216 <Checkbox className="opt__hpick" id="opt__hpick" ref={(input) => {this.optHpick = input}} 217 defaultChecked labelText="HardPick: Dealer must have suit to pick up"/> 218 <Checkbox className="opt__horder" id="opt__horder" ref={(input) => {this.optHorder = input}} 219 defaultChecked labelText="HardOrder: Must play alone if ordering partner"/> 220 <Checkbox className="opt__stick" id="opt__stick" ref={(input) => {this.optStick = input}} 221 labelText="StickDealer: Dealer must name trump if no one has" /> 222 </fieldset> 223 </ModalWrapper> 224 </div> 225 {/* planned: filterByTableName, filterByPlayerName */} 226 </div> 227 <div className="tlist__main"> 228 <div className="tlist__cntl"> 229 <Button 230 className="tlist__refresh" 231 hasIconOnly 232 onClick={this.handleRefresh} 233 renderIcon={Renew16} 234 size="small" 235 iconDescription="Refresh List" 236 tooltipPosition="bottom" 237 ref={(button) => {this.refreshButton = button;}} 238 /> 239 </div> 240 <div className="tlist__holder"> 241 <div className="tlist__list"> 242 {cards} 243 </div> 244 </div> 245 </div> 246 </div> 247 ) 248 } 249 250 } 251 TableList.propTypes = { 252 tables: PropTypes.array, 253 playerName: PropTypes.string, 254 joinTable: PropTypes.func, 255 refresh: PropTypes.func 256 }