2016-10-03 14:44:27 +13:00
|
|
|
|
|
|
|
|
import React, { PropTypes } from 'react'
|
2016-10-14 18:15:34 +13:00
|
|
|
import { connect } from 'react-redux'
|
|
|
|
|
import { bindActionCreators } from 'redux'
|
2016-10-20 21:38:01 +13:00
|
|
|
import * as mopidyActions from '../services/mopidy/actions'
|
2016-10-14 18:15:34 +13:00
|
|
|
|
2016-10-03 21:21:14 +13:00
|
|
|
import Track from './Track'
|
2016-10-03 14:44:27 +13:00
|
|
|
|
2016-10-14 18:15:34 +13:00
|
|
|
class TrackList extends React.Component{
|
2016-10-03 14:44:27 +13:00
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
|
super(props);
|
2016-10-06 16:38:06 +13:00
|
|
|
|
|
|
|
|
this.state = {
|
2016-10-17 22:00:29 +13:00
|
|
|
tracks: this.props.tracks,
|
|
|
|
|
lastSelectedTrack: false
|
2016-10-06 16:38:06 +13:00
|
|
|
}
|
2016-10-03 14:44:27 +13:00
|
|
|
}
|
|
|
|
|
|
2016-10-20 21:38:01 +13:00
|
|
|
componentWillReceiveProps( nextProps ){
|
|
|
|
|
this.setState({ tracks: nextProps.tracks });
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-17 22:00:29 +13:00
|
|
|
handleClick( e, index ){
|
2016-10-06 16:38:06 +13:00
|
|
|
var tracks = this.state.tracks;
|
2016-10-17 22:00:29 +13:00
|
|
|
|
|
|
|
|
if( e.ctrlKey ){
|
|
|
|
|
|
|
|
|
|
tracks[index].selected = !tracks[index].selected;
|
|
|
|
|
|
|
|
|
|
}else if( e.shiftKey ){
|
|
|
|
|
|
|
|
|
|
if( this.state.lastSelectedTrack < index ){
|
|
|
|
|
var start = this.state.lastSelectedTrack;
|
|
|
|
|
var end = index;
|
|
|
|
|
}else{
|
|
|
|
|
var start = index;
|
|
|
|
|
var end = this.state.lastSelectedTrack;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for( var i = start; i <= end; i++ ){
|
|
|
|
|
tracks[i].selected = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
|
|
for( var i = 0; i < tracks.length; i++ ){
|
|
|
|
|
tracks[i].selected = false;
|
|
|
|
|
}
|
|
|
|
|
tracks[index].selected = !tracks[index].selected;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.setState({ tracks: tracks, lastSelectedTrack: index });
|
2016-10-06 09:35:42 +13:00
|
|
|
}
|
|
|
|
|
|
2016-10-20 21:38:01 +13:00
|
|
|
handleDoubleClick( e, index ){
|
|
|
|
|
var tracks = this.state.tracks;
|
|
|
|
|
this.playTrack( tracks[index] )
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-19 14:09:34 +13:00
|
|
|
selectedTracks(){
|
2016-10-16 12:37:37 +13:00
|
|
|
function isSelected( track ){
|
|
|
|
|
return ( typeof(track.selected) !== 'undefined' && track.selected );
|
|
|
|
|
}
|
2016-10-19 14:09:34 +13:00
|
|
|
return this.state.tracks.filter(isSelected)
|
|
|
|
|
}
|
2016-10-16 12:37:37 +13:00
|
|
|
|
2016-10-20 21:38:01 +13:00
|
|
|
playTracks(){
|
|
|
|
|
|
|
|
|
|
var tracks = this.selectedTracks();
|
|
|
|
|
|
|
|
|
|
if( typeof(this.props.playTracks) !== 'undefined' ){
|
|
|
|
|
return this.props.playTracks( tracks );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var uris = [];
|
|
|
|
|
for( var i = 0; i < tracks.length; i++ ){
|
|
|
|
|
uris.push( tracks[i].uri )
|
|
|
|
|
}
|
|
|
|
|
return this.props.mopidyActions.playTracks( uris )
|
2016-10-19 14:09:34 +13:00
|
|
|
}
|
|
|
|
|
|
2016-10-20 21:38:01 +13:00
|
|
|
playTrack( track ){
|
|
|
|
|
|
|
|
|
|
if( typeof(this.props.playTrack) !== 'undefined' ){
|
|
|
|
|
return this.props.playTrack( this.selectedTracks() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var uris = [track.uri];
|
|
|
|
|
this.props.mopidyActions.playTracks( uris )
|
2016-10-19 14:09:34 +13:00
|
|
|
}
|
2016-10-16 12:37:37 +13:00
|
|
|
|
2016-10-19 14:09:34 +13:00
|
|
|
removeTracks(){
|
2016-10-03 14:44:27 +13:00
|
|
|
|
2016-10-20 21:38:01 +13:00
|
|
|
var tracks = this.selectedTracks();
|
|
|
|
|
|
|
|
|
|
if( typeof(this.props.removeTracks) !== 'undefined' ){
|
|
|
|
|
return this.props.removeTracks( tracks );
|
|
|
|
|
}
|
2016-10-06 16:38:06 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
render(){
|
|
|
|
|
let self = this;
|
|
|
|
|
if( this.state.tracks ){
|
2016-10-03 14:44:27 +13:00
|
|
|
return (
|
2016-10-16 12:37:37 +13:00
|
|
|
<div>
|
|
|
|
|
<ul>
|
|
|
|
|
{
|
|
|
|
|
this.state.tracks.map(
|
|
|
|
|
(track, index) => {
|
|
|
|
|
|
|
|
|
|
// flatten nested track objects (as in the case of TlTracks)
|
|
|
|
|
if( typeof(track.track) !== 'undefined' ){
|
|
|
|
|
for( var property in track.track ){
|
|
|
|
|
if( track.track.hasOwnProperty(property) ){
|
|
|
|
|
track[property] = track.track[property]
|
|
|
|
|
}
|
2016-10-06 16:38:06 +13:00
|
|
|
}
|
|
|
|
|
}
|
2016-10-16 12:37:37 +13:00
|
|
|
return <Track
|
|
|
|
|
key={index+'_'+track.uri}
|
|
|
|
|
track={track}
|
2016-10-17 22:00:29 +13:00
|
|
|
handleDoubleClick={(e) => self.handleDoubleClick(e, index)}
|
|
|
|
|
handleClick={(e) => self.handleClick(e, index)} />
|
2016-10-03 21:21:14 +13:00
|
|
|
}
|
2016-10-16 12:37:37 +13:00
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
</ul>
|
2016-10-19 14:09:34 +13:00
|
|
|
<button onClick={() => this.removeTracks()}>Delete selected</button>
|
|
|
|
|
<button onClick={() => this.playTracks()}>Play selected</button>
|
2016-10-16 12:37:37 +13:00
|
|
|
</div>
|
2016-10-03 14:44:27 +13:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2016-10-14 18:15:34 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Export our component
|
|
|
|
|
*
|
|
|
|
|
* We also integrate our global store, using connect()
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
|
|
const mapStateToProps = (state, ownProps) => {
|
|
|
|
|
return state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const mapDispatchToProps = (dispatch) => {
|
|
|
|
|
return {
|
2016-10-20 21:38:01 +13:00
|
|
|
mopidyActions: bindActionCreators(mopidyActions, dispatch)
|
2016-10-14 18:15:34 +13:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(TrackList)
|