GameHeader.js 2.5 KB

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