ChessboardInterface.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. 'use strict';
  2. import React from 'react/addons';
  3. import GameStore from '../stores/GameStore';
  4. import GameActions from '../actions/GameActions';
  5. import onGameChange from '../mixins/onGameChange';
  6. import Chessboard from './Chessboard';
  7. import CapturedPieces from './CapturedPieces';
  8. import TableOfMoves from './TableOfMoves';
  9. import cx from 'classnames';
  10. import omit from 'lodash.omit';
  11. const ChessboardInterface = React.createClass({
  12. propTypes: {
  13. io: React.PropTypes.object.isRequired,
  14. token: React.PropTypes.string.isRequired,
  15. soundsEnabled: React.PropTypes.bool.isRequired,
  16. color: React.PropTypes.oneOf(['white', 'black']).isRequired,
  17. gameOver: React.PropTypes.object.isRequired,
  18. isOpponentAvailable: React.PropTypes.bool.isRequired
  19. },
  20. mixins: [React.addons.PureRenderMixin, onGameChange],
  21. getInitialState() {
  22. return GameStore.getState();
  23. },
  24. componentDidUpdate(prevProps) {
  25. if (this.props.gameOver.get('status') &&
  26. !prevProps.gameOver.get('status')) {
  27. this.props.openModal('info', this._getGameOverMessage());
  28. }
  29. },
  30. render() {
  31. const {promotion, turn, gameOver, check} = this.state;
  32. const cxFeedback = cx({
  33. feedback: true,
  34. white: turn === 'w',
  35. black: turn === 'b'
  36. });
  37. return (
  38. <div id="board-moves-wrapper" className="clearfix">
  39. <audio preload="auto" ref="moveSnd">
  40. <source src="/snd/move.mp3" />
  41. </audio>
  42. <audio preload="auto" ref="checkSnd">
  43. <source src="/snd/check.mp3" />
  44. </audio>
  45. <div id="board-wrapper">
  46. <CapturedPieces />
  47. <Chessboard
  48. {...omit(this.props, 'soundsEnabled', 'gameOver')}
  49. gameOver={gameOver.get('status')}
  50. maybePlaySound={this._maybePlaySound} />
  51. </div>
  52. <TableOfMoves />
  53. <span className="promotion">
  54. <label>
  55. <span>Promotion: </span>
  56. <select value={promotion}
  57. onChange={this._onPromotionChange}>
  58. <option value="q">Queen</option>
  59. <option value="r">Rook</option>
  60. <option value="b">Bishop</option>
  61. <option value="n">Knight</option>
  62. </select>
  63. </label>
  64. </span>
  65. <span className={cxFeedback}>
  66. {!gameOver.get('status') ?
  67. <span>
  68. {`${turn === 'w' ? 'White' : 'Black'} to move.`}
  69. {check ? <strong> Check.</strong> : null}
  70. </span> :
  71. <strong>
  72. {this._getGameOverMessage()}
  73. </strong>
  74. }
  75. </span>
  76. </div>
  77. );
  78. },
  79. _onGameChange() {
  80. this.setState(GameStore.getState());
  81. },
  82. _onPromotionChange(e) {
  83. GameActions.changePromotion(e.target.value);
  84. },
  85. _maybePlaySound() {
  86. if (this.props.soundsEnabled) {
  87. this.refs[this.state.check ? 'checkSnd' : 'moveSnd'].getDOMNode().play();
  88. }
  89. },
  90. _getGameOverMessage() {
  91. const type = this.props.gameOver.get('type');
  92. const winner = this.props.gameOver.get('winner');
  93. const loser = winner === 'White' ? 'Black' : 'White';
  94. return type === 'checkmate' ? `Checkmate. ${winner} wins!` :
  95. type === 'timeout' ? `${loser}‘s time is out. ${winner} wins!` :
  96. type === 'resign' ? `${loser} has resigned. ${winner} wins!` :
  97. type === 'draw' ? 'Draw.' :
  98. type === 'stalemate' ? 'Draw (Stalemate).' :
  99. type === 'threefoldRepetition' ? 'Draw (Threefold Repetition).' :
  100. type === 'insufficientMaterial' ? 'Draw (Insufficient Material)' : '';
  101. }
  102. });
  103. export default ChessboardInterface;