<commit_before>import React from 'react'
import moment from 'moment'

import Counter from './Counter'
import TimerDisplay from './TimerDisplay'
import { INCREMENT, DECREMENT, statuses } from '../constants'

export default class App extends React.Component {
  constructor() {
    super()
    const workMin = 1,
          workMax = 120,
          breakMin = 1,
          breakMax = 120;
    this.state = {
      workTime: {
        selectedLength: 25,
        minLength: workMin,
        maxLength: workMax,
      },
      breakTime: {
        selectedLength: 5,
        minLength: breakMin,
        maxLength: breakMax,
      },
      // user is either working, on a break, or inactive
      session: statuses.INACTIVE,
      endTime: null, // moment.duration
      timerId: null, // number / integer
    }
    this.updateCounter = this.updateCounter.bind(this)
    this.updateSession = this.updateSession.bind(this)
    this.updateEndTime = this.updateEndTime.bind(this)
    this.getTime = this.getTime.bind(this)
    // this.startTimer = this.startTimer.bind(this)
    // this.stopTimer = this.stopTimer.bind(this)
    this.setTimerId = this.setTimerId.bind(this)
    this.handleOnClick = this.handleOnClick.bind(this)
  }

  updateCounter(counterId, action) {
    const counter = this.state[counterId],
          len = counter.selectedLength
    let newLength
    switch (action) {
      case INCREMENT:
        newLength = (len < counter.maxLength ? len + 1 : len)
        break
      case DECREMENT:
        newLength = (len > counter.minLength ? len - 1 : len)
        break
      default:
        throw new Error('unknown action')
    }
    switch (counterId) {
      case 'breakTime':
        this.setState({
          breakTime: {
            selectedLength: newLength,
            minLength: this.state.breakTime.minLength,
            maxLength: this.state.breakTime.maxLength,
          }
        })
        break
      case 'workTime':
        this.setState({
          workTime: {
            selectedLength: newLength,
            minLength: this.state.workTime.minLength,
            maxLength: this.state.workTime.maxLength,
          }
        })
        break
      default:
        throw new Error('unknown counterId')
    }
  }

  updateEndTime() {
    let newEndTime = moment.duration(
      {
        milliseconds: this.state.endTime.milliseconds(),
        seconds: this.state.endTime.seconds(),
        minutes: this.state.endTime.minutes(),
      }
    )
    newEndTime.subtract(1, 'second')
    this.setState({ endTime: newEndTime })
  }

  getTime() {
    if (this.state.session === statuses.INACTIVE) {
      return this.state.workTime.selectedLength
    }
    else {
      return this.state.endTime
    }
  }
  setTimerId(timerId) {
    this.setState({ timerId: timerId })
  }
  // startTimer() {
  //   // debugger
  //   if (!this.state.timerId) {
  //     let workDuration = moment.duration(
  //           this.state.workTime.selectedLength, 'minutes').toSeconds(),
  //     endTime = this.state.endTime.toSeconds(),
  //     newStartTime = Math.min(endTime, workDuration)
  //
  //     this.setState(
  //       { timerId: true,
  //         session: statuses.WORK,
  //         endTime: workDuration })
  //   }
  // }
  // stopTimer() {
  //   if (this.state.timerId) {
  //       clearInterval(this.state.timerId)
  //       this.setState({ timerId: null })
  //   }
  // }
  handleOnClick(event) {
    let newEndTime, newTime;
    // start the timer if it's not running
    if (!this.state.timerId) {
      const workDuration = moment.duration(
            this.state.workTime.selectedLength, 'minutes')
      // set the endTime for the first time
      if (!this.state.endTime) {
        const t = setInterval(this.updateEndTime, 1000)
        this.setState(
          { session: statuses.WORK,
            endTime: workDuration,
            timerId: t }
        )
      }
      // resume from the previous endTime
      else {
        let newEndTime = moment.duration(
          {
            milliseconds: this.state.endTime.milliseconds(),
            seconds: this.state.endTime.seconds(),
            minutes: this.state.endTime.minutes(),
          }
        )
        newTime = workDuration.asSeconds() < newEndTime.asSeconds() ? workDuration : newEndTime
        const t = setInterval(this.updateEndTime, 1000)
        this.setState(
          { timerId: t,
            session: statuses.WORK,
            endTime: newTime }
        )
      }
    }
    // stop the timer if it's running
    else if (this.state.timerId) {
      clearInterval(this.state.timerId)
      this.setState({ timerId: null })
    }
  }
  updateSession(status) {
    this.setState({ timerId: null, session: status })
  }
  render() {
    return (
      <div>
        <h1>Pomodoro Timer</h1>
        <Counter
          min={this.state.workTime.minLength}
          max={this.state.workTime.maxLength}
          increment={() => { this.updateCounter('workTime', INCREMENT) }}
          decrement={() => { this.updateCounter('workTime', DECREMENT) }}
          textBefore="Work for"
          value={this.state.workTime.selectedLength}
          textAfter="minutes"
        />
        <Counter
          min={this.state.breakTime.minLength}
          max={this.state.breakTime.maxLength}
          increment={() => { this.updateCounter('breakTime', INCREMENT) }}
          decrement={() => { this.updateCounter('breakTime', DECREMENT) }}
          textBefore="Break for"
          value={this.state.breakTime.selectedLength}
          textAfter="minutes"
        />
        <TimerDisplay
          handleOnClick={this.handleOnClick}
          getTime={this.getTime}
          endTime={this.state.endTime}
          session={this.state.session}
          timerId={this.state.timerId}
          updateEndTime={this.updateEndTime}
          setTimerId={this.setTimerId}
          updateSession={this.updateSession}
        />
      </div>
    )
  }
}
<commit_msg>refactor start/stop logic back into separate functions<commit_after>import React from 'react'
import moment from 'moment'

import Counter from './Counter'
import TimerDisplay from './TimerDisplay'
import { INCREMENT, DECREMENT, statuses } from '../constants'

export default class App extends React.Component {
  constructor() {
    super()
    const workMin = 1,
          workMax = 120,
          breakMin = 1,
          breakMax = 120;
    this.state = {
      workTime: {
        selectedLength: 25,
        minLength: workMin,
        maxLength: workMax,
      },
      breakTime: {
        selectedLength: 5,
        minLength: breakMin,
        maxLength: breakMax,
      },
      // user is either working, on a break, or inactive
      session: statuses.INACTIVE,
      endTime: null, // moment.duration
      timerId: null, // number / integer
    }
    this.updateCounter = this.updateCounter.bind(this)
    this.updateSession = this.updateSession.bind(this)
    this.updateEndTime = this.updateEndTime.bind(this)
    this.getTime = this.getTime.bind(this)
    this.startTimer = this.startTimer.bind(this)
    this.stopTimer = this.stopTimer.bind(this)
    this.setTimerId = this.setTimerId.bind(this)
    this.handleOnClick = this.handleOnClick.bind(this)
  }

  updateCounter(counterId, action) {
    const counter = this.state[counterId],
          len = counter.selectedLength
    let newLength
    switch (action) {
      case INCREMENT:
        newLength = (len < counter.maxLength ? len + 1 : len)
        break
      case DECREMENT:
        newLength = (len > counter.minLength ? len - 1 : len)
        break
      default:
        throw new Error('unknown action')
    }
    switch (counterId) {
      case 'breakTime':
        this.setState({
          breakTime: {
            selectedLength: newLength,
            minLength: this.state.breakTime.minLength,
            maxLength: this.state.breakTime.maxLength,
          }
        })
        break
      case 'workTime':
        this.setState({
          workTime: {
            selectedLength: newLength,
            minLength: this.state.workTime.minLength,
            maxLength: this.state.workTime.maxLength,
          }
        })
        break
      default:
        throw new Error('unknown counterId')
    }
  }

  updateEndTime() {
    let newEndTime = moment.duration(
      {
        milliseconds: this.state.endTime.milliseconds(),
        seconds: this.state.endTime.seconds(),
        minutes: this.state.endTime.minutes(),
      }
    )
    newEndTime.subtract(1, 'second')
    this.setState({ endTime: newEndTime })
  }

  getTime() {
    if (this.state.session === statuses.INACTIVE) {
      return this.state.workTime.selectedLength
    }
    else {
      return this.state.endTime
    }
  }
  setTimerId(timerId) {
    this.setState({ timerId: timerId })
  }
  startTimer() {
    let workDuration = moment.duration(
        this.state.workTime.selectedLength, 'minutes')

    if (this.state.endTime === null) {
      // set the endTime for the first time
      if (!this.state.endTime) {
        const t = setInterval(this.updateEndTime, 1000)
        this.setState(
          { session: statuses.WORK,
            endTime: workDuration,
            timerId: t }
        )
      }
    }
    // resume from the previous endTime
    else {
      const newEndTime = moment.duration(
        {
          milliseconds: this.state.endTime.milliseconds(),
          seconds: this.state.endTime.seconds(),
          minutes: this.state.endTime.minutes(),
        }
      )
      const newTime = workDuration.asSeconds() < newEndTime.asSeconds() ?
          workDuration : newEndTime
      const t = setInterval(this.updateEndTime, 1000)
      this.setState(
        { timerId: t,
          session: statuses.WORK,
          endTime: newTime }
      )
    }
  }
  stopTimer() {
    if (this.state.timerId) {
        clearInterval(this.state.timerId)
        this.setState({ timerId: null })
    }
  }
  handleOnClick(event) {
    if (!this.state.timerId) {
      this.startTimer()
    }
    else {
      this.stopTimer()
    }
  }
  updateSession(status) {
    this.setState({ timerId: null, session: status })
  }
  render() {
    return (
      <div>
        <h1>Pomodoro Timer</h1>
        <Counter
          min={this.state.workTime.minLength}
          max={this.state.workTime.maxLength}
          increment={() => { this.updateCounter('workTime', INCREMENT) }}
          decrement={() => { this.updateCounter('workTime', DECREMENT) }}
          textBefore="Work for"
          value={this.state.workTime.selectedLength}
          textAfter="minutes"
        />
        <Counter
          min={this.state.breakTime.minLength}
          max={this.state.breakTime.maxLength}
          increment={() => { this.updateCounter('breakTime', INCREMENT) }}
          decrement={() => { this.updateCounter('breakTime', DECREMENT) }}
          textBefore="Break for"
          value={this.state.breakTime.selectedLength}
          textAfter="minutes"
        />
        <TimerDisplay
          handleOnClick={this.handleOnClick}
          getTime={this.getTime}
          endTime={this.state.endTime}
          session={this.state.session}
          timerId={this.state.timerId}
          updateEndTime={this.updateEndTime}
          setTimerId={this.setTimerId}
          updateSession={this.updateSession}
        />
      </div>
    )
  }
}

{'fraction_non_alphanumeric': 0.11767800771659068, 'fraction_numerical': 0.004209049456331112, 'mean_word_length': 2.03728362183755, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 27, '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': '6092659', 'n_tokens_mistral': 3398, 'n_tokens_neox': 3361, 'n_words': 642}