<commit_before>import React, {PropTypes} from 'react';
import ReactDOM from 'react-dom';
import {connect} from 'react-redux';
import * as actions from '../../actions';
import {bindActionCreators} from 'redux';
import _ from 'lodash';

// try to get local api key or from env
// if(process.env.NODE_ENV === 'production') {
//   var CLIENT_ID = process.env.SC_KEY;
// } else {
//   var CLIENT_ID = require('../../constants/auth').CLIENT_ID;
// }
// import { CLIENT_ID } from '../../constants/auth';

class Player extends React.Component {
  constructor(props, context) {
    super(props, context);

    // local player state
    this.state = {
      currentAudioTime: 0,
      currentAudioDuration: 0,
      currentVolumeLevel: 100
    };

    this.onTogglePlay = this.onTogglePlay.bind(this);
    this.displayTrackInfo = this.displayTrackInfo.bind(this);

    // audio controls
    this.handleAudioPlayed = this.handleAudioPlayed.bind(this);
    this.handleAudioPaused = this.handleAudioPaused.bind(this);

    // seekbar
    this.handleAudioTimeUpdate = this.handleAudioTimeUpdate.bind(this);
    this.handleSeeked = this.handleSeeked.bind(this);
    this.handleAudioTimeUpdate = this.handleAudioTimeUpdate.bind(this);
    this.onSeekbarChange = this.onSeekbarChange.bind(this);

    // volume controls
    this.onVolumeLevelChange = this.onVolumeLevelChange.bind(this);
    this.handleVolumeUpdated = this.handleVolumeUpdated.bind(this);
    
    // track change events
    this.onNextTrack = this.onNextTrack.bind(this);
    this.onPrevTrack = this.onPrevTrack.bind(this);
    this.handleAudioEnded = this.handleAudioEnded.bind(this);

    // format util function
    this.formatStreamURL = this.formatStreamURL.bind(this);
  }

  // Lifecycle components
  componentDidMount() {
    const audioElement = ReactDOM.findDOMNode(this.refs.audio);

    // update ui icons based on audio element changes directly
    audioElement.addEventListener('play', this.handleAudioPlayed, false);
    audioElement.addEventListener('pause', this.handleAudioPaused, false);
    audioElement.addEventListener('timeupdate', this.handleAudioTimeUpdate, false);
    audioElement.addEventListener('seeked', this.handleSeeked, false);
    audioElement.addEventListener('volumechange', this.handleVolumeUpdated, false);
    audioElement.addEventListener('ended', this.handleAudioEnded, false);
  }

  // compare changed activeTrack and automaticaly play song if activeTrack is different
  // from the previous;
  // additionally, set local state's duration
  componentDidUpdate(prevProps) {
    const audioElement = ReactDOM.findDOMNode(this.refs.audio);
    const { activeTrackIndex, playlist } = this.props;

    if(activeTrackIndex !== undefined && activeTrackIndex !== prevProps.activeTrackIndex) {
      const activeTrack = playlist[activeTrackIndex];
      const duration = Math.floor(activeTrack.duration);

      this.setState({
        currentAudioDuration: duration
      });

      audioElement.play();
    }
  }

  // clean up event listeners on dismount
  componentWillUnmount() {
    const audioElement = ReactDOM.findDOMNode(this.refs.audio);

    audioElement.removeEventListener('play', this.handleAudioPlayed, false);
    audioElement.removeEventListener('pause', this.handleAudioPaused, false);
    audioElement.removeEventListener('timeupdate', this.handleAudioTimeUpdate, false);
    audioElement.removeEventListener('seeked', this.handleSeeked, false);
    audioElement.removeEventListener('volumechange', this.handleVolumeUpdated, false);
  }

  // toggle redux store to show audio is playing
  // should only change if an active track is available
  handleAudioPlayed() {
    const { activeTrackIndex } = this.props;
    if(activeTrackIndex !== undefined) this.props.actions.togglePlaying(true);
  }
  
  // toggle redux store playing state to pause
  handleAudioPaused() {
    const { activeTrackIndex } = this.props;
    if(activeTrackIndex !== undefined) this.props.actions.togglePlaying(false);
  }

  handleAudioTimeUpdate(e) {
    const time = Math.floor(e.target.currentTime);
    this.setState({
      currentAudioTime: time
    });
  }

  // handles event for when audio element's time is changed via a seek event.
  // should update component state to reflect change<commit_msg>added remove event listener on component unmount for ended event<commit_after>import React, {PropTypes} from 'react';
import ReactDOM from 'react-dom';
import {connect} from 'react-redux';
import * as actions from '../../actions';
import {bindActionCreators} from 'redux';
import _ from 'lodash';

// try to get local api key or from env
// if(process.env.NODE_ENV === 'production') {
//   var CLIENT_ID = process.env.SC_KEY;
// } else {
//   var CLIENT_ID = require('../../constants/auth').CLIENT_ID;
// }
// import { CLIENT_ID } from '../../constants/auth';

class Player extends React.Component {
  constructor(props, context) {
    super(props, context);

    // local player state
    this.state = {
      currentAudioTime: 0,
      currentAudioDuration: 0,
      currentVolumeLevel: 100
    };

    this.onTogglePlay = this.onTogglePlay.bind(this);
    this.displayTrackInfo = this.displayTrackInfo.bind(this);

    // audio controls
    this.handleAudioPlayed = this.handleAudioPlayed.bind(this);
    this.handleAudioPaused = this.handleAudioPaused.bind(this);

    // seekbar
    this.handleAudioTimeUpdate = this.handleAudioTimeUpdate.bind(this);
    this.handleSeeked = this.handleSeeked.bind(this);
    this.handleAudioTimeUpdate = this.handleAudioTimeUpdate.bind(this);
    this.onSeekbarChange = this.onSeekbarChange.bind(this);

    // volume controls
    this.onVolumeLevelChange = this.onVolumeLevelChange.bind(this);
    this.handleVolumeUpdated = this.handleVolumeUpdated.bind(this);
    
    // track change events
    this.onNextTrack = this.onNextTrack.bind(this);
    this.onPrevTrack = this.onPrevTrack.bind(this);
    this.handleAudioEnded = this.handleAudioEnded.bind(this);

    // format util function
    this.formatStreamURL = this.formatStreamURL.bind(this);
  }

  // Lifecycle components
  componentDidMount() {
    const audioElement = ReactDOM.findDOMNode(this.refs.audio);

    // update ui icons based on audio element changes directly
    audioElement.addEventListener('play', this.handleAudioPlayed, false);
    audioElement.addEventListener('pause', this.handleAudioPaused, false);
    audioElement.addEventListener('timeupdate', this.handleAudioTimeUpdate, false);
    audioElement.addEventListener('seeked', this.handleSeeked, false);
    audioElement.addEventListener('volumechange', this.handleVolumeUpdated, false);
    audioElement.addEventListener('ended', this.handleAudioEnded, false);
  }

  // compare changed activeTrack and automaticaly play song if activeTrack is different
  // from the previous;
  // additionally, set local state's duration
  componentDidUpdate(prevProps) {
    const audioElement = ReactDOM.findDOMNode(this.refs.audio);
    const { activeTrackIndex, playlist } = this.props;

    if(activeTrackIndex !== undefined && activeTrackIndex !== prevProps.activeTrackIndex) {
      const activeTrack = playlist[activeTrackIndex];
      const duration = Math.floor(activeTrack.duration);

      this.setState({
        currentAudioDuration: duration
      });

      audioElement.play();
    }
  }

  // clean up event listeners on dismount
  componentWillUnmount() {
    const audioElement = ReactDOM.findDOMNode(this.refs.audio);

    audioElement.removeEventListener('play', this.handleAudioPlayed, false);
    audioElement.removeEventListener('pause', this.handleAudioPaused, false);
    audioElement.removeEventListener('timeupdate', this.handleAudioTimeUpdate, false);
    audioElement.removeEventListener('seeked', this.handleSeeked, false);
    audioElement.removeEventListener('volumechange', this.handleVolumeUpdated, false);
    audioElement.removeEventListener('ended', this.handleAudioEnded, false);
  }

  // toggle redux store to show audio is playing
  // should only change if an active track is available
  handleAudioPlayed() {
    const { activeTrackIndex } = this.props;
    if(activeTrackIndex !== undefined) this.props.actions.togglePlaying(true);
  }
  
  // toggle redux store playing state to pause
  handleAudioPaused() {
    const { activeTrackIndex } = this.props;
    if(activeTrackIndex !== undefined) this.props.actions.togglePlaying(false);
  }

  handleAudioTimeUpdate(e) {
    const time = Math.floor(e.target.currentTime);
    this.setState({
      currentAudioTime: time
    });
  }

  // handles event for when audio element's time is changed via a seek event.
  // should update component state to reflect change
{'fraction_non_alphanumeric': 0.11176200321617276, 'fraction_numerical': 0.0011486331265793705, 'mean_word_length': 4.006900517538815, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '6063366', 'n_tokens_mistral': 2468, 'n_tokens_neox': 2401, 'n_words': 547}