Reordering local playlist tracks; Lazy-loading track details
This commit is contained in:
@ -61,7 +61,7 @@ export default class Track extends React.Component{
|
||||
onContextMenu={ e => this.handleContextMenu(e) }>
|
||||
{ this.props.track.selected ? <FontAwesome name="check" className="select-state" fixedWidth /> : null }
|
||||
<span className="col name">
|
||||
{ track.name ? track.name : '-' }
|
||||
{ track.name ? track.name : track.uri }
|
||||
</span>
|
||||
<span className="col artists">
|
||||
{ track.artists ? <ArtistSentence artists={track.artists} /> : '-' }
|
||||
|
||||
@ -95,8 +95,12 @@ class TrackList extends React.Component{
|
||||
|
||||
handleMouseUp(e, index){
|
||||
if( this.props.dragger && this.props.dragger.active ){
|
||||
var indexes = this.props.dragger.victims_indexes
|
||||
this.props.uiActions.reorderTracks(this.props.context, indexes, index)
|
||||
|
||||
// if this tracklist handles sorting, handle it
|
||||
if( typeof(this.props.reorderTracks) !== 'undefined' ){
|
||||
var indexes = this.props.dragger.victims_indexes
|
||||
return this.props.reorderTracks( indexes, index );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ const localstorageMiddleware = (function(){
|
||||
|
||||
// append our state to a global variable. This gives us access to debug the store at any point
|
||||
window._store = store
|
||||
//console.log(action)
|
||||
console.log(action)
|
||||
|
||||
switch( action.type ){
|
||||
|
||||
|
||||
@ -225,48 +225,48 @@ const MopidyMiddleware = (function(){
|
||||
tracks_total: ( response.tracks ? response.tracks.length : 0 )
|
||||
}
|
||||
)
|
||||
|
||||
var uris = [];
|
||||
for( var i = 0; i < playlist.tracks.length; i++ ){
|
||||
uris.push( playlist.tracks[i].uri );
|
||||
}
|
||||
|
||||
// no tracks
|
||||
if( uris.length <= 0 ){
|
||||
store.dispatch({ type: 'MOPIDY_PLAYLIST_LOADED', data: playlist });
|
||||
// tracks? get the full track objects
|
||||
if( playlist.tracks.length > 0 ) store.dispatch({ type: 'MOPIDY_FETCH_PLAYLIST_TRACKS', tracks: playlist.tracks })
|
||||
|
||||
// tracks? let's flesh them out with full track objects, rather than just reference objects
|
||||
}else{
|
||||
instruct( socket, store, 'library.lookup', { uris: uris } )
|
||||
.then( response => {
|
||||
|
||||
for(var uri in response){
|
||||
if (response.hasOwnProperty(uri)) {
|
||||
|
||||
var track = response[uri][0];
|
||||
if( track ){
|
||||
|
||||
// find the track reference, and drop in the full track data
|
||||
function getByURI( trackReference ){
|
||||
return track.uri == trackReference.uri
|
||||
}
|
||||
var trackReferences = playlist.tracks.filter(getByURI);
|
||||
|
||||
// there could be multiple instances of this track, so accommodate this
|
||||
for( var j = 0; j < trackReferences.length; j++){
|
||||
var key = playlist.tracks.indexOf( trackReferences[j] );
|
||||
playlist.tracks[ key ] = track;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
store.dispatch({ type: 'MOPIDY_PLAYLIST_LOADED', data: playlist });
|
||||
})
|
||||
}
|
||||
store.dispatch({ type: 'MOPIDY_PLAYLIST_LOADED', data: playlist })
|
||||
})
|
||||
break;
|
||||
|
||||
case 'MOPIDY_FETCH_PLAYLIST_TRACKS':
|
||||
var tracks = Object.assign([], action.tracks)
|
||||
var uris = [];
|
||||
for( var i = 0; i < tracks.length; i++ ){
|
||||
uris.push( tracks[i].uri );
|
||||
}
|
||||
|
||||
instruct( socket, store, 'library.lookup', { uris: uris } )
|
||||
.then( response => {
|
||||
for(var uri in response){
|
||||
if (response.hasOwnProperty(uri)) {
|
||||
|
||||
var track = response[uri][0]
|
||||
if( track ){
|
||||
|
||||
// find the track reference, and drop in the full track data
|
||||
function getByURI( trackReference ){
|
||||
return track.uri == trackReference.uri
|
||||
}
|
||||
var trackReferences = tracks.filter(getByURI);
|
||||
|
||||
// there could be multiple instances of this track, so accommodate this
|
||||
for( var j = 0; j < trackReferences.length; j++){
|
||||
var key = tracks.indexOf( trackReferences[j] );
|
||||
tracks[ key ] = track;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
store.dispatch({ type: 'PLAYLIST_TRACKS_LOADED', tracks: tracks })
|
||||
})
|
||||
break
|
||||
|
||||
case 'MOPIDY_ADD_PLAYLIST_TRACKS':
|
||||
|
||||
instruct( socket, store, 'playlists.lookup', { uri: action.playlist_uri })
|
||||
@ -339,6 +339,48 @@ const MopidyMiddleware = (function(){
|
||||
});
|
||||
break
|
||||
|
||||
case 'MOPIDY_REORDER_PLAYLIST_TRACKS':
|
||||
instruct( socket, store, 'playlists.lookup', { uri: action.uri })
|
||||
.then( response => {
|
||||
|
||||
var playlist = Object.assign({}, response)
|
||||
var tracks = Object.assign([], playlist.tracks)
|
||||
var tracks_to_move = []
|
||||
|
||||
// calculate destination index: if dragging down, accommodate the offset created by the tracks we're moving
|
||||
var to_index = action.to_index
|
||||
var indexes = action.indexes
|
||||
var range_start = indexes[0]
|
||||
var range_length = indexes.length
|
||||
if( to_index > range_start ) to_index = to_index - range_length
|
||||
|
||||
// collate our tracks to be moved
|
||||
for( var i = 0; i < indexes.length; i++ ){
|
||||
|
||||
// add to FRONT: we work backwards to avoid screwing up our indexes
|
||||
tracks_to_move.unshift( tracks[indexes[i]] )
|
||||
}
|
||||
|
||||
// remove tracks from their old location
|
||||
// BIG ASSUMPTION: this is one continuious set of indexes, ie not 1,2,5,6,9
|
||||
tracks.splice( range_start, range_length )
|
||||
|
||||
// now plug them back in, in their new location
|
||||
for( var i = 0; i < tracks_to_move.length; i++ ){
|
||||
tracks.splice( to_index, 0, tracks_to_move[i] )
|
||||
}
|
||||
|
||||
// update playlist
|
||||
playlist = Object.assign({}, playlist, { tracks: tracks })
|
||||
instruct( socket, store, 'playlists.save', { playlist: playlist } )
|
||||
.then( response => {
|
||||
|
||||
// and now re-render our full track references
|
||||
store.dispatch({ type: 'MOPIDY_FETCH_PLAYLIST_TRACKS', tracks: playlist.tracks })
|
||||
})
|
||||
});
|
||||
break
|
||||
|
||||
case 'MOPIDY_DELETE_PLAYLIST':
|
||||
instruct( socket, store, 'playlists.delete', { uri: action.uri })
|
||||
.then( response => {
|
||||
|
||||
@ -59,22 +59,23 @@ export function dragEnd(){
|
||||
return { type: 'DRAG_END' }
|
||||
}
|
||||
|
||||
export function reorderTracks( context, indexes, destination_index ){
|
||||
console.log('uiActions.reorderTracks', context, indexes, destination_index)
|
||||
switch( context ){
|
||||
export function reorderPlaylistTracks( uri, indexes, to_index ){
|
||||
switch( helpers.uriSource( uri ) ){
|
||||
|
||||
case 'queue':
|
||||
case 'spotify':
|
||||
return {
|
||||
type: 'MOPIDY_REORDER_TRACKLIST',
|
||||
type: 'SPOTIFY_REORDER_PLAYLIST_TRACKS',
|
||||
uri: uri,
|
||||
indexes: indexes,
|
||||
destination_index: destination_index
|
||||
to_index: to_index
|
||||
}
|
||||
|
||||
case 'editable-playlist':
|
||||
case 'm3u':
|
||||
return {
|
||||
type: 'SPOTIFY_REORDER_TRACKLIST',
|
||||
type: 'MOPIDY_REORDER_PLAYLIST_TRACKS',
|
||||
uri: uri,
|
||||
indexes: indexes,
|
||||
destination_index: destination_index
|
||||
to_index: to_index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,20 +221,28 @@ export default function reducer(ui = {}, action){
|
||||
|
||||
case 'PLAYLIST_TRACKS_REMOVED':
|
||||
var tracks = Object.assign([], ui.playlist.tracks)
|
||||
for( var i = 0; i < action.tracks_indexes.length; i++ ){
|
||||
tracks.splice( action.tracks_indexes[i], 1 )
|
||||
var indexes = action.tracks_indexes.reverse()
|
||||
for( var i = 0; i < indexes.length; i++ ){
|
||||
tracks.splice( indexes[i], 1 )
|
||||
}
|
||||
var snapshot_id = null
|
||||
if( action.snapshot_id ) snapshot_id = action.snapshot_id
|
||||
var playlist = Object.assign({}, ui.playlist, { tracks: tracks, snapshot_id: snapshot_id })
|
||||
return Object.assign({}, ui, { playlist: playlist });
|
||||
|
||||
case 'PLAYLIST_TRACKS_LOADED':
|
||||
var playlist = Object.assign({}, ui.playlist, { tracks: action.tracks })
|
||||
return Object.assign({}, ui, { playlist: playlist });
|
||||
|
||||
case 'PLAYLIST_TRACKS_REORDERED':
|
||||
var snapshot_id = null
|
||||
if( action.snapshot_id ) snapshot_id = action.snapshot_id
|
||||
var playlist = Object.assign({}, ui.playlist, { tracks: action.tracks, snapshot_id: snapshot_id })
|
||||
return Object.assign({}, ui, { playlist: playlist });
|
||||
|
||||
|
||||
/**
|
||||
* Library Playlists
|
||||
*
|
||||
* TODO: Map sources and merge any replicated URIS
|
||||
*
|
||||
**/
|
||||
|
||||
case 'MOPIDY_PLAYLISTS_LOADED':
|
||||
|
||||
@ -73,8 +73,12 @@ class Playlist extends React.Component{
|
||||
this.props.mopidyActions.deletePlaylist( this.props.params.uri )
|
||||
}
|
||||
|
||||
removeTracks( track_indexes ){
|
||||
this.props.uiActions.removeTracksFromPlaylist( this.props.playlist.uri, track_indexes )
|
||||
reorderTracks( indexes, index ){
|
||||
this.props.uiActions.reorderPlaylistTracks( this.props.playlist.uri, indexes, index )
|
||||
}
|
||||
|
||||
removeTracks( tracks_indexes ){
|
||||
this.props.uiActions.removeTracksFromPlaylist( this.props.playlist.uri, tracks_indexes )
|
||||
}
|
||||
|
||||
renderEditButtons(){
|
||||
@ -138,7 +142,7 @@ class Playlist extends React.Component{
|
||||
</div>
|
||||
|
||||
<section className="list-wrapper">
|
||||
{ this.props.playlist.tracks ? <TrackList context="editable-playlist" tracks={ this.props.playlist.tracks } removeTracks={ track_indexes => this.removeTracks(track_indexes) } /> : null }
|
||||
{ this.props.playlist.tracks ? <TrackList context="editable-playlist" tracks={ this.props.playlist.tracks } removeTracks={ tracks_indexes => this.removeTracks(tracks_indexes) } reorderTracks={ (indexes, index) => this.reorderTracks(indexes, index) } /> : null }
|
||||
<LazyLoadListener loadMore={ () => this.loadMore() }/>
|
||||
</section>
|
||||
|
||||
|
||||
@ -37,6 +37,10 @@ class Queue extends React.Component{
|
||||
this.props.mopidyActions.changeTrack( tracks[0].tlid )
|
||||
}
|
||||
|
||||
reorderTracks( indexes, index ){
|
||||
this.props.mopidyActions.reorderTracklist( indexes, index )
|
||||
}
|
||||
|
||||
render(){
|
||||
return (
|
||||
<div className="view queue-view">
|
||||
@ -50,7 +54,8 @@ class Queue extends React.Component{
|
||||
tracks={this.props.current_tracklist}
|
||||
removeTracks={ tracks => this.removeTracks( tracks ) }
|
||||
playTracks={ tracks => this.playTracks( tracks ) }
|
||||
playTrack={ track => this.playTrack( track ) } />
|
||||
playTrack={ track => this.playTrack( track ) }
|
||||
reorderTracks={ (indexes, index) => this.reorderTracks(indexes, index) } />
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user