GameHeader.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import React from 'react/addons';
  2. import omit from 'lodash.omit';
  3. import Clock from './Clock';
  4. import ChatStore from '../stores/ChatStore';
  5. import ChatActions from '../actions/ChatActions';
  6. const GameHeader = React.createClass({
  7. propTypes: {
  8. io: React.PropTypes.object.isRequired,
  9. params: React.PropTypes.array.isRequired,
  10. color: React.PropTypes.oneOf(['white', 'black']).isRequired,
  11. openModal: React.PropTypes.func.isRequired,
  12. gameOver: React.PropTypes.bool.isRequired,
  13. isOpponentAvailable: React.PropTypes.bool.isRequired
  14. },
  15. mixins: [React.addons.PureRenderMixin],
  16. getInitialState() {
  17. return omit(ChatStore.getState(), 'messages');
  18. },
  19. componentDidMount() {
  20. ChatStore.on('change', this._onChatChange);
  21. },
  22. componentWillUnmount() {
  23. ChatStore.off('change', this._onChatChange);
  24. },
  25. render() {
  26. const {io, params, gameOver, isOpponentAvailable} = this.props;
  27. const unseenCount = this.state.unseenCount;
  28. return (
  29. <header className="clearfix">
  30. <Clock
  31. io={io}
  32. params={params} />
  33. <span id="game-type">
  34. {`${params[1]}|${params[2]}`}
  35. </span>
  36. <a className="btn" href="/">New game</a>
  37. {!gameOver && isOpponentAvailable ?
  38. <a className="btn btn--red resign"
  39. onClick={this._onResign}>
  40. Resign
  41. </a>
  42. :gameOver ?
  43. <a className="btn btn--red rematch"
  44. onClick={this._onRematch}>
  45. Rematch
  46. </a>
  47. :null}
  48. <a id="chat-icon"
  49. onClick={ChatActions.toggleVisibility}>
  50. {unseenCount ?
  51. <span id="chat-counter">
  52. {unseenCount < 9 ? unseenCount : '9+'}
  53. </span>
  54. :null}
  55. <img src="/img/chat.svg"
  56. width="50"
  57. height="50" />
  58. Chat
  59. </a>
  60. </header>
  61. );
  62. },
  63. _onChatChange() {
  64. this.setState(omit(ChatStore.getState(), 'messages'));
  65. },
  66. _onResign() {
  67. const {io, params, color} = this.props;
  68. io.emit('resign', {
  69. token: params[0],
  70. color: color
  71. });
  72. },
  73. _onRematch() {
  74. const {io, params, openModal, isOpponentAvailable} = this.props;
  75. if (!isOpponentAvailable) {
  76. openModal('info', 'Your opponent has disconnected. You need to ' +
  77. 'generate a new link.');
  78. return;
  79. }
  80. io.emit('rematch-offer', {
  81. token: params[0]
  82. });
  83. openModal('info', 'Your offer has been sent.');
  84. }
  85. });
  86. export default GameHeader;