<commit_before>import _ from 'lodash';
import React, { Component, PropTypes } from 'react';
import { SemaphoreColors } from './../helpers';

const UP = 'up';
const DOWN = 'down';
const DOWN_KEY = 40;
const UP_KEY = 38;
const NUMBERS_KEYS = _.range(48, 58);
const SECONDS_FOR_COMBINE_NUMBERS = 0.8;

class VerticalSlider extends Component {
  constructor(props) {
    super(props);
    const { value } = props;
    // Binds
    this.onScroll = this.onScroll.bind(this);
    this.onKeyDown = this.onKeyDown.bind(this);
    // Init
    this.resetScrollVars();
    this.resetNumberPressVars();
    this.state = { currentValue: value };
  }

  componentWillReceiveProps(newProps) {
    const { onOpen } = this.props
    if(!!newProps.open) {
      $('body').addClass('no-scroll')
      $('body').on('keydown', this.onKeyDown);
    } else {
      $('body').removeClass('no-scroll');
      $('body').off('keydown', this.onKeyDown);
    }
    // Call on open prop
    const isOpening = newProps.open !== this.props.open && newProps.open === OPEN;
    if(isOpening && onOpen) onOpen();
  }

  submitHandler(event) {
    if(!!event) event.preventDefault();
    const { onSubmit, onClose } = this.props;
    if(onSubmit) onSubmit();
    if(onClose) onClose();
  }

  stopParentClickPropagation(event) {
    event.stopPropagation();
  }

  resetScrollVars() {
    this.lastDeltaY = 0;
    this.previousDeltaY = 0;
    this.lastStepsScrolled = 0;
    this.deltaYLimit = 10;
  }

  resetNumberPressVars() {
    this.lastTimePressed = null;
    this.lastKeysPresseds = [];
  }

  onScroll(event) {
    if(Math.abs(event.deltaY) === 0) this.resetScrollVars();
    const direction = event.deltaY < 0 ? UP : DOWN;
    const isChanging = direction === UP ? event.deltaY > this.lastDeltaY : event.deltaY < this.lastDeltaY;
    if(isChanging) direction === UP ? this.increaseValue() : this.decreaseValue();
    this.lastDeltaY = event.deltaY;
  }

  onKeyDown(event) {
    const { keyCode } = event;
    if(keyCode === UP_KEY) this.increaseValue();
    if(keyCode === DOWN_KEY) this.decreaseValue();
    if(_.includes(NUMBERS_KEYS, keyCode)) this.handleNumberPress(keyCode);
  }

  handleNumberPress(keyCode) {
    const currentDate = new Date();
    const intervalInSeconds = (currentDate - this.lastTimePressed) / 1000;
    if(intervalInSeconds > SECONDS_FOR_COMBINE_NUMBERS) this.resetNumberPressVars();
    this.lastTimePressed = currentDate;
    this.lastKeysPresseds.push(keyCode);
    const newValue = _.map(this.lastKeysPresseds, (key) => String.fromCharCode(key)).join('');
    this.setNewValue(Number(newValue));
  }

  increaseValue() {
    const { step } = this.props;
    const { currentValue } = this.state;
    this.setNewValue(currentValue + step);
  }

  decreaseValue() {
    const { step } = this.props;
    const { currentValue } = this.state;
    this.setNewValue(currentValue - step);
  }

  setNewValue(newValue) {
    const { max, min } = this.props;
    if(newValue > max) newValue = max;
    if(newValue < min) newValue = min;
    this.setState({ currentValue: newValue });
  }

  stopParentClickPropagation(event) {
    event.stopPropagation();
  }

  renderNextValue(iterator, size) {
    const { min, max } = this.props;
    const { currentValue } = this.state;
    const value = currentValue + iterator;<commit_msg>Vertical slider with floating decimal option<commit_after>import _ from 'lodash';
import React, { Component, PropTypes } from 'react';
import { SemaphoreColors } from './../helpers';

const UP = 'up';
const DOWN = 'down';
const DOWN_KEY = 40;
const UP_KEY = 38;
const NUMBERS_KEYS = _.range(48, 58);
const SECONDS_FOR_COMBINE_NUMBERS = 0.8;

class VerticalSlider extends Component {
  constructor(props) {
    super(props);
    const { value } = props;
    // Binds
    this.onScroll = this.onScroll.bind(this);
    this.onKeyDown = this.onKeyDown.bind(this);
    // Init
    this.resetScrollVars();
    this.resetNumberPressVars();
    this.handleOpenCloseEvents(props);
    this.state = { currentValue: value };
  }

  componentWillReceiveProps(newProps) {
    const { onOpen } = this.props
    this.handleOpenCloseEvents(newProps);
    // Call on open prop
    const isOpening = newProps.open !== this.props.open && newProps.open === OPEN;
    if(isOpening && onOpen) onOpen();
  }

  componentWillUnmount() {
    this.handleOpenCloseEvents({});
  }

  handleOpenCloseEvents(newProps) {
    if(!!newProps.open) {
      $('body').addClass('no-scroll')
      $('body').on('keydown', this.onKeyDown);
    } else {
      $('body').removeClass('no-scroll');
      $('body').off('keydown', this.onKeyDown);
    }
  }

  submitHandler(event) {
    if(!!event) event.preventDefault();
    const { onSubmit, onClose } = this.props;
    if(onSubmit) onSubmit();
    if(onClose) onClose();
  }

  stopParentClickPropagation(event) {
    event.stopPropagation();
  }

  resetScrollVars() {
    this.lastDeltaY = 0;
    this.previousDeltaY = 0;
    this.lastStepsScrolled = 0;
    this.deltaYLimit = 10;
  }

  resetNumberPressVars() {
    this.lastTimePressed = null;
    this.lastKeysPresseds = [];
  }

  onScroll(event) {
    if(Math.abs(event.deltaY) === 0) this.resetScrollVars();
    const direction = event.deltaY < 0 ? UP : DOWN;
    const isChanging = direction === UP ? event.deltaY > this.lastDeltaY : event.deltaY < this.lastDeltaY;
    if(isChanging) direction === UP ? this.increaseValue() : this.decreaseValue();
    this.lastDeltaY = event.deltaY;
  }

  onKeyDown(event) {
    const { keyCode } = event;
    if(keyCode === UP_KEY) this.increaseValue();
    if(keyCode === DOWN_KEY) this.decreaseValue();
    if(_.includes(NUMBERS_KEYS, keyCode)) this.handleNumberPress(keyCode);
  }

  handleNumberPress(keyCode) {
    const currentDate = new Date();
    const intervalInSeconds = (currentDate - this.lastTimePressed) / 1000;
    if(intervalInSeconds > SECONDS_FOR_COMBINE_NUMBERS) this.resetNumberPressVars();
    this.lastTimePressed = currentDate;
    this.lastKeysPresseds.push(keyCode);
    const newValue = _.map(this.lastKeysPresseds, (key) => String.fromCharCode(key)).join('');
    this.setNewValue(Number(newValue));
  }

  getDecimalPrecision() {
    const { step } = this.props;
    const brokenStep = step.toString().split('.');
    const hasDecimal = _.size(brokenStep) > 1;
    if(!hasDecimal) return 0;
    return _.size(_.last(brokenStep));
  }

  increaseValue() {
    const { step } = this.props;
    const { currentValue } = this.state;
    this.setNewValue(currentValue + step);
  }

  decreaseValue() {
    const { step } = this.props;
    const { currentValue } = this.state;
    this.setNewValue(currentValue - step);
  }

  setNewValue(newValue) {
    const { max, min } = this.props;
    if(newValue > max) newValue = max;
    if(newValue < min) newValue = min;
    newValue =  _.round(newValue, this.getDecimalPrecision());
    this.setState({ currentValue: newValue });
  }

  stopParentClickPropagation(event) {
    event.stopPropagation();
  }

  renderNextValue(iterator, size) {
    const { min, max, step } = this.props;
    const { currentValue } = this.state;
    const value = _.round(currentValue + (iterator * step), this.getDecimalPrecision());
{'fraction_non_alphanumeric': 0.14317394317394316, 'fraction_numerical': 0.006098406098406098, 'mean_word_length': 3.4903546981953952, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 12, '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': '639946', 'n_tokens_mistral': 2457, 'n_tokens_neox': 2399, 'n_words': 455}