ChessboardInterface.js 3.7 KB

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