diff --git a/src/js/helpers.js b/src/js/helpers.js index ab094638..5367f211 100755 --- a/src/js/helpers.js +++ b/src/js/helpers.js @@ -179,4 +179,35 @@ export let mergeDuplicates = function(list, key){ } return clean_list; +} + +/** + * Convert a list of indexes to a useable range + * We ignore stragglers, and only attend to the first 'bunch' of consecutive indexes + * + * @param indexes array of int + **/ +export let createRange = function (indexes){ + + // sort our indexes smallest to largest + function sortAsc(a,b){ + return a - b + } + indexes.sort(sortAsc); + + // iterate indexes to build the first 'bunch' + var first_bunch = [] + var previous_index = false + for( var i = 0; i < indexes.length; i++ ){ + if( !previous_index || previous_index == indexes[i]-1 ){ + first_bunch.push(indexes[i]) + previous_index = indexes[i] + } + // TODO: break when we find an integer step for better performance + } + + return { + start: first_bunch[0], + length: first_bunch.length + } } \ No newline at end of file diff --git a/src/js/services/mopidy/actions.js b/src/js/services/mopidy/actions.js index 5901c070..4265fe13 100755 --- a/src/js/services/mopidy/actions.js +++ b/src/js/services/mopidy/actions.js @@ -1,7 +1,5 @@ -/** - * Actions and Action Creators - **/ +import * as helpers from '../../helpers' export function setConfig( config ){ return { @@ -69,6 +67,16 @@ export function removeTracks( tlids ){ } } +export function reorderTracklist( indexes, insert_before ){ + var range = helpers.createRange( indexes ); + return { + type: 'MOPIDY_REORDER_TRACKLIST', + range_start: range.start, + range_length: range.length, + insert_before: insert_before + } +} + export function play(){ return instruct('playback.play'); } diff --git a/src/js/services/mopidy/middleware.js b/src/js/services/mopidy/middleware.js index 3b28efbc..8f8c08e7 100755 --- a/src/js/services/mopidy/middleware.js +++ b/src/js/services/mopidy/middleware.js @@ -1,7 +1,7 @@ import Mopidy from 'mopidy' +import * as helpers from '../../helpers' -var helpers = require('../../helpers.js') var mopidyActions = require('./actions.js') var lastfmActions = require('../lastfm/actions.js') @@ -200,6 +200,15 @@ const MopidyMiddleware = (function(){ }) break; + case 'MOPIDY_REORDER_TRACKLIST': + + // add our first track + instruct( socket, store, 'tracklist.move', { start: action.range_start, end: action.range_start + action.range_length, to_position: action.insert_before } ) + .then( response => { + console.log(response) + }) + break; + case 'MOPIDY_PLAYLISTS': instruct( socket, store, 'playlists.asList' ) .then( response => { @@ -348,26 +357,24 @@ const MopidyMiddleware = (function(){ 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 + var range_start = action.range_start + var range_length = action.range_length + var insert_before = action.insert_before + if( insert_before > range_start ) insert_before = insert_before - range_length // collate our tracks to be moved - for( var i = 0; i < indexes.length; i++ ){ + for( var i = 0; i < range_length; i++ ){ // add to FRONT: we work backwards to avoid screwing up our indexes - tracks_to_move.unshift( tracks[indexes[i]] ) + tracks_to_move.unshift( tracks[range_start + 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] ) + tracks.splice( insert_before, 0, tracks_to_move[i] ) } // update playlist diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js index a15288e7..d0afb863 100755 --- a/src/js/services/spotify/actions.js +++ b/src/js/services/spotify/actions.js @@ -641,17 +641,15 @@ export function deleteTracksFromPlaylist( uri, snapshot_id, tracks_indexes ){ } } -export function reorderPlaylistTracks( uri, indexes, to_index, snapshot_id ){ - var range_start = indexes[0] - var range_length = indexes.length +export function reorderPlaylistTracks( uri, range_start, range_length, insert_before, snapshot_id ){ return (dispatch, getState) => { - sendRequest( dispatch, getState, 'users/'+ helpers.getFromUri('userid',uri) + '/playlists/'+ helpers.getFromUri('playlistid',uri) + '/tracks', 'PUT', { uri: uri, range_start: range_start, range_length: range_length, insert_before: to_index, snapshot_id: snapshot_id } ) + sendRequest( dispatch, getState, 'users/'+ helpers.getFromUri('userid',uri) + '/playlists/'+ helpers.getFromUri('playlistid',uri) + '/tracks', 'PUT', { uri: uri, range_start: range_start, range_length: range_length, insert_before: insert_before, snapshot_id: snapshot_id } ) .then( response => { dispatch({ type: 'PLAYLIST_TRACKS_REORDERED', range_start: range_start, range_length: range_length, - to_index: to_index, + insert_before: insert_before, snapshot_id: response.snapshot_id }); }); diff --git a/src/js/services/spotify/middleware.js b/src/js/services/spotify/middleware.js index 26a72bb4..f0186925 100755 --- a/src/js/services/spotify/middleware.js +++ b/src/js/services/spotify/middleware.js @@ -58,7 +58,7 @@ const SpotifyMiddleware = (function(){ alert('Must be logged in to Spotify to do this') return } - store.dispatch( actions.reorderPlaylistTracks( action.uri, action.indexes, action.to_index )) + store.dispatch( actions.reorderPlaylistTracks( action.uri, action.range_start, action.range_length, action.insert_before, action.snapshot_id )) break diff --git a/src/js/services/ui/actions.js b/src/js/services/ui/actions.js index d00b996a..086a454b 100755 --- a/src/js/services/ui/actions.js +++ b/src/js/services/ui/actions.js @@ -59,16 +59,17 @@ export function dragEnd(){ return { type: 'DRAG_END' } } -export function reorderPlaylistTracks( uri, indexes, to_index, snapshot_id = false ){ +export function reorderPlaylistTracks( uri, indexes, insert_before, snapshot_id = false ){ + var range = helpers.createRange( indexes ); switch( helpers.uriSource( uri ) ){ case 'spotify': - // TODO: handle bunched selected tracks (ie non-continuious indexes) return { type: 'SPOTIFY_REORDER_PLAYLIST_TRACKS', uri: uri, - indexes: indexes, - to_index: to_index, + range_start: range.start, + range_length: range.length, + insert_before: insert_before, snapshot_id: snapshot_id } @@ -76,8 +77,9 @@ export function reorderPlaylistTracks( uri, indexes, to_index, snapshot_id = fal return { type: 'MOPIDY_REORDER_PLAYLIST_TRACKS', uri: uri, - indexes: indexes, - to_index: to_index + range_start: range.start, + range_length: range.length, + insert_before: insert_before } } } diff --git a/src/js/services/ui/reducer.js b/src/js/services/ui/reducer.js index 11a9fa96..e6821bb4 100755 --- a/src/js/services/ui/reducer.js +++ b/src/js/services/ui/reducer.js @@ -233,13 +233,26 @@ export default function reducer(ui = {}, action){ 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 }) + var tracks = Object.assign([], ui.playlist.tracks) + + // handle insert_before offset if we're moving BENEATH where we're slicing tracks + var insert_before = action.insert_before + if( insert_before > action.range_start ) insert_before = insert_before - action.range_length + + // cut our moved tracks into a new array + var tracks_to_move = tracks.splice(action.range_start, action.range_length) + tracks_to_move.reverse() + + for( i = 0; i < tracks_to_move.length; i++ ){ + tracks.splice(insert_before, 0, tracks_to_move[i]) + } + + var playlist = Object.assign({}, ui.playlist, { snapshot_id: snapshot_id, tracks: tracks }) return Object.assign({}, ui, { playlist: playlist }); -*/ /** * Library Playlists