<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Popover from 'material-ui/Popover';
import TextField from 'material-ui/TextField';
import set from 'lodash/set';

import AddButton from '../AddButton';
import RemoveButton from '../RemoveButton';
import YellowCardIcon from '../YellowCardIcon';
import RedCardIcon from '../RedCardIcon';
import GoalIcon from '../GoalIcon';
import AssistIcon from '../AssistIcon';
import styles from './PlayerPopover.scss';
import pt from '../../propTypes';

export default class PlayerPopover extends Component {
  constructor(props) {
    super(props);

    this.handleChange = this.handleChange.bind(this);
    this.handleKeyDown = this.handleKeyDown.bind(this);
  }

  componentDidMount() {
    window.addEventListener('keydown', this.handleKeyDown);
  }

  shouldComponentUpdate(nextProps) {
    return this.props.player !== nextProps.player;
  }

  componentWillUnmount() {
    window.removeEventListener('keydown', this.handleKeyDown);
  }

  handleChange(path, newVal, test) {
    const { player, onPlayerChange } = this.props;
    if (!test || test(newVal)) {
      const result = set({}, path, newVal);
      onPlayerChange(player.id, result);
    }
  }

  handleKeyDown(e) {
    if (e.key === 'Enter' || e.key === 'Escape') {
      this.props.onRequestClose();
    }
  }

  renderButtons(path, val, label, validate) {
    return (
    [
      <RemoveButton
        className={styles.button}
        key={`remove.${path}`}
        tooltip={`Remove ${label}`}
        disabled={!validate(val - 1)}
        onTouchTap={() =>
          this.handleChange(path, val - 1, validate)}
      />,
      <AddButton
        className={styles.button}
        key={`add.${path}`}
        tooltip={`Add ${label}`}
        disabled={!validate(val + 1)}
        onTouchTap={() =>
          this.handleChange(path, val + 1, validate)}
      />,
    ]);
  }

  render() {
    const { player } = this.props;

    const validate = {
      goals: val => val >= 0 && val <= 5,
      assists: val => val >= 0 && val <= 5,
      cards: {
        yellow: val => val >= 0 && val <= 2,
        red: val => val >= 0 && val <= 1,
      },
      number: val => val >= 0 && val <= 99,
      rating: val => val >= 1 && val <= 10,
      name: val => val.length >= 0 && val.length <= 15,
    };

    return (
      <Popover
        className={styles.wrapper}
        open={!!this.props.player}
        anchorEl={this.props.anchorEl}
        anchorOrigin={{ horizontal: 'middle', vertical: 'bottom' }}
        targetOrigin={{ horizontal: 'middle', vertical: 'top' }}
        onRequestClose={this.props.onRequestClose}
        useLayerForClickAway
      >
        <ul className={styles.list}>
          <li>
            <YellowCardIcon className={styles.card} />
            {this.renderButtons('cards.yellow', player.cards.yellow, 'Yellow Card',
              validate.cards.yellow)}
          </li>
          <li>
            <GoalIcon className={styles.ball} />
            {this.renderButtons('goals', player.goals, 'Goal', validate.goals)}
          </li>
          <li>
            <RedCardIcon className={styles.card} />
            {this.renderButtons('cards.red', player.cards.red, 'Red Card', validate.cards.red)}
          </li>
          <li>
            <AssistIcon className={styles.ball} />
            {this.renderButtons('assists', player.assists, 'Assist', validate.assists)}
          </li>
          <li className={styles.fullWidth}>
            <TextField
              className={styles.numberField}
              floatingLabelText="Number"
              floatingLabelFixed
              name="number"
              type="number"
              value={player.number <= 0 ? '' : player.number}
              onChange={e =>
                this.handleChange('number', +e.target.value, validate.number)}
              min={1}
              max={99}
            />
            <TextField
              className={styles.ratingField}
              floatingLabelText="Rating"
              floatingLabelFixed
              name="rating"
              type="number"
              value={player.rating <= 0 ? '' : player.rating}
              onChange={e =>
                this.handleChange('rating', +e.target.value, validate.rating)}
              min={1}
              max={10}
            />
            <TextField
              className={styles.nameField}
              floatingLabelText="Name"
              floatingLabelFixed
              name="name"
              value={player.name}
              onChange={e => this.handleChange('name', e.target.value, validate.name)}
              autoFocus
            />
          </li>
        </ul>
      </Popover>
    );
  }
}

PlayerPopover.defaultProps = {
  anchorEl: null,
};

PlayerPopover.propTypes = {
  player: pt.player.isRequired,
  onRequestClose: PropTypes.func.isRequired,
  onPlayerChange: PropTypes.func.isRequired,
  anchorEl: PropTypes.object, // eslint-disable-line react/forbid-prop-types
};<commit_msg>Debounce state change on PlayerPopover input<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Popover from 'material-ui/Popover';
import TextField from 'material-ui/TextField';
import set from 'lodash/set';
import debounce from 'lodash/debounce';

import AddButton from '../AddButton';
import RemoveButton from '../RemoveButton';
import YellowCardIcon from '../YellowCardIcon';
import RedCardIcon from '../RedCardIcon';
import GoalIcon from '../GoalIcon';
import AssistIcon from '../AssistIcon';
import styles from './PlayerPopover.scss';
import pt from '../../propTypes';

export default class PlayerPopover extends Component {
  constructor(props) {
    super(props);

    this.handleChange = this.handleChange.bind(this);
    this.handleKeyDown = this.handleKeyDown.bind(this);
    this.debouncedOnPlayerChange = debounce(props.onPlayerChange.bind(this), 100);

    const { name, number, rating, goals, assists, cards } = props.player;
    this.state = { name, number, rating, goals, assists, cards };
  }

  componentDidMount() {
    window.addEventListener('keydown', this.handleKeyDown);
  }

  shouldComponentUpdate(nextProps, nextState) {
    return (this.props.player !== nextProps.player) || (this.state !== nextState);
  }

  componentWillUnmount() {
    window.removeEventListener('keydown', this.handleKeyDown);
  }

  handleChange(path, newVal, test) {
    const { player } = this.props;
    if (!test || test(newVal)) {
      const result = set(this.state, path, newVal);
      this.setState(prevState => ({ ...prevState, ...result }));
      this.debouncedOnPlayerChange(player.id, result);
    }
  }

  handleKeyDown(e) {
    if (e.key === 'Enter' || e.key === 'Escape') {
      this.props.onRequestClose();
    }
  }

  renderButtons(path, val, label, validate) {
    return (
    [
      <RemoveButton
        className={styles.button}
        key={`remove.${path}`}
        tooltip={`Remove ${label}`}
        disabled={!validate(val - 1)}
        onTouchTap={() =>
          this.handleChange(path, val - 1, validate)}
      />,
      <AddButton
        className={styles.button}
        key={`add.${path}`}
        tooltip={`Add ${label}`}
        disabled={!validate(val + 1)}
        onTouchTap={() =>
          this.handleChange(path, val + 1, validate)}
      />,
    ]);
  }

  render() {
    const { name, number, rating, goals, assists, cards } = this.state;

    const validate = {
      goals: val => val >= 0 && val <= 5,
      assists: val => val >= 0 && val <= 5,
      cards: {
        yellow: val => val >= 0 && val <= 2,
        red: val => val >= 0 && val <= 1,
      },
      number: val => val >= 0 && val <= 99,
      rating: val => val >= 1 && val <= 10,
      name: val => val.length >= 0 && val.length <= 15,
    };

    return (
      <Popover
        className={styles.wrapper}
        open={!!this.props.player}
        anchorEl={this.props.anchorEl}
        anchorOrigin={{ horizontal: 'middle', vertical: 'bottom' }}
        targetOrigin={{ horizontal: 'middle', vertical: 'top' }}
        onRequestClose={this.props.onRequestClose}
        useLayerForClickAway
      >
        <ul className={styles.list}>
          <li>
            <YellowCardIcon className={styles.card} />
            {this.renderButtons('cards.yellow', cards.yellow, 'Yellow Card',
              validate.cards.yellow)}
          </li>
          <li>
            <GoalIcon className={styles.ball} />
            {this.renderButtons('goals', goals, 'Goal', validate.goals)}
          </li>
          <li>
            <RedCardIcon className={styles.card} />
            {this.renderButtons('cards.red', cards.red, 'Red Card', validate.cards.red)}
          </li>
          <li>
            <AssistIcon className={styles.ball} />
            {this.renderButtons('assists', assists, 'Assist', validate.assists)}
          </li>
          <li className={styles.fullWidth}>
            <TextField
              className={styles.numberField}
              floatingLabelText="Number"
              floatingLabelFixed
              name="number"
              type="number"
              value={number <= 0 ? '' : number}
              onChange={e =>
                this.handleChange('number', +e.target.value, validate.number)}
              min={1}
              max={99}
            />
            <TextField
              className={styles.ratingField}
              floatingLabelText="Rating"
              floatingLabelFixed
              name="rating"
              type="number"
              value={rating <= 0 ? '' : rating}
              onChange={e =>
                this.handleChange('rating', +e.target.value, validate.rating)}
              min={1}
              max={10}
            />
            <TextField
              className={styles.nameField}
              floatingLabelText="Name"
              floatingLabelFixed
              name="name"
              value={name}
              onChange={e => this.handleChange('name', e.target.value, validate.name)}
              autoFocus
            />
          </li>
        </ul>
      </Popover>
    );
  }
}

PlayerPopover.defaultProps = {
  anchorEl: null,
};

PlayerPopover.propTypes = {
  player: pt.player.isRequired,
  onRequestClose: PropTypes.func.isRequired,
  onPlayerChange: PropTypes.func.isRequired,
  anchorEl: PropTypes.object, // eslint-disable-line react/forbid-prop-types
};
{'fraction_non_alphanumeric': 0.14547712293437767, 'fraction_numerical': 0.005826726525933709, 'mean_word_length': 2.132854578096948, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 88, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '657552', 'n_tokens_mistral': 3022, 'n_tokens_neox': 2978, 'n_words': 617}