{ track.artists ? : '-' }
diff --git a/src/js/components/TrackList.js b/src/js/components/TrackList.js
index 0281fd19..edc28637 100755
--- a/src/js/components/TrackList.js
+++ b/src/js/components/TrackList.js
@@ -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 );
+ }
}
}
diff --git a/src/js/services/localstorage/middleware.js b/src/js/services/localstorage/middleware.js
index db626418..71932e75 100755
--- a/src/js/services/localstorage/middleware.js
+++ b/src/js/services/localstorage/middleware.js
@@ -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 ){
diff --git a/src/js/services/mopidy/middleware.js b/src/js/services/mopidy/middleware.js
index 1b5752b2..8ce77ca7 100755
--- a/src/js/services/mopidy/middleware.js
+++ b/src/js/services/mopidy/middleware.js
@@ -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 => {
diff --git a/src/js/services/ui/actions.js b/src/js/services/ui/actions.js
index ee0c64cd..067cc292 100755
--- a/src/js/services/ui/actions.js
+++ b/src/js/services/ui/actions.js
@@ -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
}
}
}
diff --git a/src/js/services/ui/reducer.js b/src/js/services/ui/reducer.js
index 3d332e28..645af616 100755
--- a/src/js/services/ui/reducer.js
+++ b/src/js/services/ui/reducer.js
@@ -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':
diff --git a/src/js/views/Playlist.js b/src/js/views/Playlist.js
index 8090ff0e..6d35feeb 100755
--- a/src/js/views/Playlist.js
+++ b/src/js/views/Playlist.js
@@ -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{
- { this.props.playlist.tracks ? this.removeTracks(track_indexes) } /> : null }
+ { this.props.playlist.tracks ? this.removeTracks(tracks_indexes) } reorderTracks={ (indexes, index) => this.reorderTracks(indexes, index) } /> : null }
this.loadMore() }/>
diff --git a/src/js/views/Queue.js b/src/js/views/Queue.js
index 29f723e3..81760c66 100755
--- a/src/js/views/Queue.js
+++ b/src/js/views/Queue.js
@@ -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 (
@@ -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) } />