diff --git a/src/js/components/ContextMenu.js b/src/js/components/ContextMenu.js index 94327e14..84373b4c 100755 --- a/src/js/components/ContextMenu.js +++ b/src/js/components/ContextMenu.js @@ -201,7 +201,7 @@ class ContextMenu extends React.Component{ goToRecommendations(e){ this.props.uiActions.hideContextMenu() - var uris_string = helpers.asURIs(this.props.menu.items).join(',') + var uris_string = helpers.arrayOf('uri',this.props.menu.items).join(',') hashHistory.push( global.baseURL +'discover/recommendations/'+ uris_string ) } diff --git a/src/js/components/Track.js b/src/js/components/Track.js index 00ff344b..d804a6bf 100755 --- a/src/js/components/Track.js +++ b/src/js/components/Track.js @@ -15,25 +15,58 @@ export default class Track extends React.Component{ this.state = { hover: false } + + this.drag_threshold = 5 + this.start_position = false } handleMouseDown(e){ - var target = $(e.target); - if( !target.is('a') && target.closest('a').length <= 0 ){ - this.props.handleMouseDown(e); + this.start_position = { + x: e.pageX, + y: e.pageY } } - handleTouchEnd(e){ - var target = $(e.target); - if( !target.is('a') && target.closest('a').length <= 0 ){ - this.props.handleTouchEnd(e); + handleMouseMove(e){ + + // No drag handling means no + if (this.props.handleDrag === undefined){ + return false + } + + if (this.start_position){ + let start_x = this.start_position.x + let start_y = this.start_position.y + let threshold = 5 + + // Have we dragged outside of our threshold zone? + if (e.pageX > start_x + threshold || e.pageX < start_x - threshold || e.pageY > start_y + threshold || e.pageY < start_y - threshold){ + + // Handover to parent for dragging. We can unset all our behaviour now. + this.props.handleDrag(e) + this.start_position = false + } } } - handleContextMenu(e){ - e.preventDefault(); - this.props.handleContextMenu(e); + handleMouseUp(e){ + if (this.props.dragger){ + e.preventDefault() + + if (this.props.handleDrop !== undefined){ + this.props.handleDrop(e) + } + } else { + var target = $(e.target); + if( !target.is('a') && target.closest('a').length <= 0 ){ + this.props.handleSelection(e) + this.start_position = false + } + } + } + + handleTouchStart(e){ + this.props.handleTouchDrag(e) } render(){ @@ -42,6 +75,7 @@ export default class Track extends React.Component{ var track = this.props.track var className = 'list-item track' if (this.props.selected) className += ' selected' + if (this.props.can_sort) className += ' can-sort' if (track.type !== undefined) className += ' '+track.type if (track.playing) className += ' playing' if (this.state.hover) className += ' hover' @@ -55,113 +89,154 @@ export default class Track extends React.Component{ } } + let track_columns = [] + if (track.type == 'history'){ - var track_columns = ( - - - {this.props.track.selected ? : null} - - - {track.name ? track.name : {track.uri}} - - - {helpers.uriSource(track.uri)} - - - {track.played_at ? ago : null} - + track_columns.push( + + {track.name ? track.name : {track.uri}} + + ) + track_columns.push( + + {helpers.uriSource(track.uri)} + + ) + track_columns.push( + + {track.played_at ? ago : null} ) } else if (this.props.context == 'queue'){ - if (track.added_from && track.added_by){ - var type = (track.added_from ? helpers.uriType(track.added_from) : null) - if (type == 'discover'){ - var link = discover - } else { - var link = {type} - } - var added = {track.added_by} (from {link}) - - } else if (track.added_by){ - var added = track.added_by - + if (track.added_from && track.added_by){ + var type = (track.added_from ? helpers.uriType(track.added_from) : null) + if (type == 'discover'){ + var link = discover } else { - var added = '-' + var link = {type} } + var added = {track.added_by} (from {link}) - className+= ' has-drag-zone' + } else if (track.added_by){ + var added = track.added_by - var track_columns = ( - - - {this.props.track.selected ? : null} - - - - - - {track.name ? track.name : {track.uri}} - {track.explicit ? EXPLICIT : null} - - {this.props.show_source_icon ? : null} - - {track.artists ? : '-'} - - - {album} - - - {added} - - - {track.duration_ms ? : null} - {track.length ? : null} - - + } else { + var added = '-' + } + + track_columns.push( + + {track.name ? track.name : {track.uri}} + {track.explicit ? EXPLICIT : null} + + ) + if (this.props.show_source_icon){ + track_columns.push( + ) + } + track_columns.push( + + {track.artists ? : '-'} + + ) + track_columns.push( + + {album} + + ) + track_columns.push( + + {added} + + ) + track_columns.push( + + {track.duration_ms ? : null} + {track.length ? : null} + + ) } else { - var track_columns = ( - - - {this.props.track.selected ? : null} - - - {track.name ? track.name : {track.uri}} - {track.explicit ? EXPLICIT : null} - - {this.props.show_source_icon ? : null} - - {track.artists ? : '-'} - - - {album} - - - {track.duration_ms ? : null} - {track.length ? : null} - + track_columns.push( + + {track.name ? track.name : {track.uri}} + {track.explicit ? EXPLICIT : null} + + ) + if (this.props.show_source_icon){ + track_columns.push( + + ) + } + track_columns.push( + + {track.artists ? : '-'} + + ) + track_columns.push( + + {album} + + ) + track_columns.push( + + {track.duration_ms ? : null} + {track.length ? : null} ) } - return ( -
this.setState({hover: true})} - onMouseLeave={e => this.setState({hover: false})} - onTouchStart={ e => this.props.handleTouchStart(e) } - onTouchEnd={ e => this.handleTouchEnd(e) } - onMouseDown={ e => this.handleMouseDown(e) } - onMouseUp={ e => this.props.handleMouseUp(e) } - onDoubleClick={ e => this.props.handleDoubleClick(e) } - onContextMenu={ e => this.handleContextMenu(e) }> + if (this.props.slim_mode){ + + // Select zone handles selection events only + // We use onClick to capture touch as well as mouse events in one tidy parcel + track_columns.push( + this.props.handleSelection(e)}> + {this.props.selected ? : null} + + ) + + if (this.props.can_sort){ + track_columns.push( + this.handleTouchStart(e)}> + + + ) + } + + // No events attached directly to the track. Instead events are attached to + // the appropriate select/drag zone sub-elements + return ( +
{ track_columns } -
- ); +
+ ) + } else { + return ( +
this.setState({hover: true})} + onMouseLeave={e => this.setState({hover: false})} + onTouchEnd={e => this.handleTouchEnd(e)} // When touch dragging is dropped on me + onMouseDown={e => this.handleMouseDown(e)} // Click (or potentially a mouse drag start) + onMouseMove={e => this.handleMouseMove(e)} // Any movement over me + onMouseUp={e => this.handleMouseUp(e)} // End of click, or potentially a dragging drop event + onDoubleClick={e => this.props.handleDoubleClick(e)} + onContextMenu={e => {e.preventDefault(); this.props.handleContextMenu(e)}}> + { track_columns } +
+ ) + } } } \ No newline at end of file diff --git a/src/js/components/TrackList.js b/src/js/components/TrackList.js index d356dc7c..e7a4b1e9 100755 --- a/src/js/components/TrackList.js +++ b/src/js/components/TrackList.js @@ -16,19 +16,23 @@ class TrackList extends React.Component{ constructor(props) { super(props) - this.touch_dragging = false + this.touch_dragging_tracks_keys = false + this.handleKeyUp = this.handleKeyUp.bind(this) this.handleTouchMove = this.handleTouchMove.bind(this) + this.handleTouchEnd = this.handleTouchEnd.bind(this) } componentWillMount(){ window.addEventListener("keyup", this.handleKeyUp, false) window.addEventListener("touchmove", this.handleTouchMove, false) + window.addEventListener("touchend", this.handleTouchEnd, false) } componentWillUnmount(){ window.removeEventListener("keyup", this.handleKeyUp, false) window.removeEventListener("touchmove", this.handleTouchMove, false) + window.removeEventListener("touchend", this.handleTouchEnd, false) } /** @@ -68,7 +72,7 @@ class TrackList extends React.Component{ } handleKeyUp(e){ - if (!this.selectedTracks()) return + if (!this.digestTracksKeys()) return switch(e.keyCode){ @@ -82,18 +86,62 @@ class TrackList extends React.Component{ } } - handleTouchStart(e,index){ - var target = $(e.target) - if (target.hasClass('drag-zone')){ - $('body').addClass('touch-dragging') - this.touch_dragging = true - e.preventDefault() + handleDrag(e,track_key){ + + let selected_tracks = [] + + // Dragging a non-selected track. We need to deselect everything + // else and select only this track + if (!this.props.selected_tracks.includes(track_key)){ + this.props.uiActions.setSelectedTracks([track_key]) + selected_tracks = this.digestTracksKeys([track_key]) + } else { + selected_tracks = this.digestTracksKeys() + } + + let selected_tracks_indexes = helpers.arrayOf('index',selected_tracks) + + this.props.uiActions.dragStart( + e, + this.props.context, + this.props.uri, + selected_tracks, + selected_tracks_indexes + ) + } + + handleDrop(e,track_key){ + if (this.props.dragger && this.props.dragger.active){ + + // if this tracklist handles sorting, handle it + if (this.props.reorderTracks !== undefined){ + let indexes = this.props.dragger.victims_indexes + let tracks = this.digestTracksKeys([track_key]) + return this.props.reorderTracks(indexes, tracks[0].index) + } + } + this.touch_dragging_tracks_keys = false + } + + handleTouchDrag(e,track_key){ + let selected_tracks = [] + + // Drag initiated on a selected track + if (this.props.selected_tracks.includes(track_key)){ + + // They're all dragging + this.touch_dragging_tracks_keys = this.props.selected_tracks + + // Not already selected + } else { + this.touch_dragging_tracks_keys = [track_key] + this.props.uiActions.setSelectedTracks([track_key]) } } handleTouchMove(e){ - if (this.touch_dragging){ - e.preventDefault() + if (this.touch_dragging_tracks_keys){ + let touch = e.touches[0] let over = $(document.elementFromPoint(touch.clientX, touch.clientY)) if (!over.is('.track')){ @@ -103,11 +151,17 @@ class TrackList extends React.Component{ if (over.length > 0){ over.addClass('touch-drag-hover') } + + e.returnValue = false + e.cancelBubble = true + e.preventDefault() + e.stopPropagation() + return false } } - handleTouchEnd(e,index){ - if (this.touch_dragging){ + handleTouchEnd(e){ + if (this.touch_dragging_tracks_keys){ let touch = e.changedTouches[0] let over = $(document.elementFromPoint(touch.clientX, touch.clientY)) if (!over.is('.track')){ @@ -117,22 +171,16 @@ class TrackList extends React.Component{ let siblings = over.parent().children('.track') let dropped_at = siblings.index(over) - 1 - if (typeof(this.props.reorderTracks) !== 'undefined'){ - this.props.reorderTracks([index],dropped_at) - this.render() + if (this.props.reorderTracks !== undefined){ + this.props.reorderTracks(helpers.arrayOf('index',this.digestTracksKeys()),dropped_at) } } $(document).find('.touch-drag-hover').removeClass('touch-drag-hover') $('body').removeClass('touch-dragging') - this.touch_dragging = false - } else { - this.handleMouseDown(e,index) } - - // Prevent any event bubbling. This prevents clicks and mouse events - // from also being fired - e.preventDefault() + + this.touch_dragging_tracks_keys = false } handleDoubleClick(e,track_key){ @@ -140,76 +188,29 @@ class TrackList extends React.Component{ this.playTracks() } - handleMouseDown(e,track_key){ - if (this.props.context_menu) this.props.uiActions.hideContextMenu() - - - this.toggleTrackSelections(e, track_key) - - if (this.props.dragger && this.props.dragger.active){ - - // 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 ) - } - } -/* - // Regular clicking an un-selected element - // This selects the track before we potentially drag - switch (this.triggerType(e)){ - - case 'mobile': - // simple toggle - var tracks = this.state.tracks - tracks[index].selected = !tracks[index].selected - this.setState({tracks: tracks, last_selected_track: index}) - break - - case 'default': - if (!this.state.tracks[index].selected && !this.isRightClick(e) && !e.ctrlKey){ - this.toggleTrackSelections(e, index) - } - break - } - */ - - //this.props.uiActions.dragStart(e, this.props.context, this.props.uri, selected_tracks, this.tracksIndexes(selected_tracks)) - } - - handleMouseUp(e,track_key){ - } - handleContextMenu(e, native_event = true){ + let selected_tracks = this.digestTracksKeys() + let selected_tracks_uris = helpers.arrayOf('uri',selected_tracks) + let selected_tracks_indexes = helpers.arrayOf('index',selected_tracks) - // Only enable direct context menu events in default (desktop) view - // This prevents tap-and-hold functionality - if (native_event && this.triggerType(e) != 'default'){ - return false - } - - var selected_tracks = this.selectedTracks() - var data = { + let data = { e: e, context: (this.props.context ? this.props.context+'-track' : 'track'), tracklist_uri: (this.props.uri ? this.props.uri : null), items: selected_tracks, - uris: helpers.asURIs(selected_tracks), - indexes: this.tracksIndexes(selected_tracks) + uris: selected_tracks_uris, + indexes: selected_tracks_indexes } this.props.uiActions.showContextMenu(data) - if (!native_event){ - - // Deselect all tracks - this.props.uiActions.setSelectedTracks([]) - } + // Deselect all tracks + this.props.uiActions.setSelectedTracks([]) } - toggleTrackSelections(e,track_key){ + handleSelection(e,track_key){ let selected_tracks = this.props.selected_tracks - if (e.ctrlKey){ + if (e.ctrlKey || this.props.slim_mode){ // Already selected, so unselect it if (selected_tracks.includes(track_key)){ @@ -261,67 +262,63 @@ class TrackList extends React.Component{ return false } - keyifyTracks(tracks, deselect = false){ - for( var i = 0; i < tracks.length; i++ ){ - var new_properties = { - key: i+'_'+tracks[i].uri - } - if (deselect){ - new_properties.selected = false - } - tracks[i] = Object.assign( - {}, - tracks[i], - new_properties - ) - } - return tracks - } - selectedTracks(indexes_only = false){ - if (!this.props.selected_tracks){ + /** + * Digest our selected tracks + * + * @param tracks = array (defaults to stored value) + * @param indexex_only = boolean (do we just want an array of indexes) + * @return mixed + **/ + digestTracksKeys(keys = this.props.selected_tracks, indexes_only = false){ + if (!keys || keys.length <= 0){ return false } // Construct a basic track object, based on our unique track key // This is enough to perform interactions (dragging, selecting, etc) - let response = [] - for (let i = 0; i < this.props.selected_tracks.length; i++){ - let track = this.props.selected_tracks[i].split('_') + let array = [] + for (let i = 0; i < keys.length; i++){ + let key = keys[i].split('_') if (indexes_only){ - response.push(track[0]) + array.push(key[0]) } else { - response.push({ - index: track[0], - uri: track[1], - context: track[2], - context_uri: track[3] + array.push({ + index: parseInt(key[0]), + uri: key[1], + context: key[2], + context_uri: key[3] }) } } - return response + return array } playTracks(){ - let selected_tracks = this.selectedTracks() + let selected_tracks = this.digestTracksKeys() + let selected_tracks_indexes = helpers.arrayOf('index',selected_tracks) // Our parent handles playing if (this.props.playTracks !== undefined){ - return this.props.playTracks( selected_tracks ); - } + return this.props.playTracks( selected_tracks ) // Default to playing the URIs - return this.props.mopidyActions.playURIs(helpers.asURIs(selected_tracks), this.props.uri ) + } else { + let selected_tracks_uris = helpers.arrayOf('uri',selected_tracks) + return this.props.mopidyActions.playURIs(selected_tracks_uris, this.props.uri) + } } removeTracks(){ // Our parent handles removal if (this.props.removeTracks !== undefined){ - return this.props.removeTracks(this.selectedTracks(true)) + let selected_tracks = this.digestTracksKeys() + let selected_tracks_indexes = helpers.arrayOf('index',selected_tracks) + return this.props.removeTracks(selected_tracks_indexes) } // By default, do nothing @@ -387,19 +384,23 @@ class TrackList extends React.Component{ key={track_key} track={track} context={this.props.context} + can_sort={this.props.context == 'queue' || this.props.context == 'editable-playlist'} + slim_mode={this.props.slim_mode} selected={this.props.selected_tracks.includes(track_key)} + dragger={this.props.dragger} + handleSelection={e => this.handleSelection(e, track_key)} handleDoubleClick={e => this.handleDoubleClick(e, track_key)} - handleMouseUp={e => this.handleMouseUp(e, track_key)} - handleMouseDown={e => this.handleMouseDown(e, track_key)} - handleTouchStart={e => this.handleTouchStart(e, track_key)} - handleTouchEnd={e => this.handleTouchEnd(e, track_key)} handleContextMenu={e => this.handleContextMenu(e)} + handleDrag={e => this.handleDrag(e, track_key)} + handleDrop={e => this.handleDrop(e, track_key)} + handleTouchDrag={e => this.handleTouchDrag(e, track_key)} + handleTouchDrop={e => this.handleTouchDrop(e, track_key)} /> ) } ) } - {this.selectedTracks() ? this.handleContextMenu(e, false)} /> : null} + {this.digestTracksKeys() ? this.handleContextMenu(e, false)} /> : null} ); } diff --git a/src/js/helpers.js b/src/js/helpers.js index e196057e..ac7c99ec 100755 --- a/src/js/helpers.js +++ b/src/js/helpers.js @@ -271,17 +271,18 @@ export let indexFriendlyUri = function (uri){ /** - * Digest an array of objects, and pull into simple array of uris + * Digest an array of objects and pull into simple array of one property * - * @param items Array + * @param property = string + * @param items = Array * @return Array **/ -export let asURIs = function(items){ - var uris = [] - for( var i = 0; i < items.length; i++ ){ - uris.push( items[i].uri ) +export let arrayOf = function(property, items){ + let array = [] + for (let i = 0; i < items.length; i++){ + array.push(items[i][property]) } - return uris + return array } diff --git a/src/js/services/mopidy/middleware.js b/src/js/services/mopidy/middleware.js index 58a4e4cd..fd4990ab 100755 --- a/src/js/services/mopidy/middleware.js +++ b/src/js/services/mopidy/middleware.js @@ -286,7 +286,7 @@ const MopidyMiddleware = (function(){ if (typeof(response.tracks) === 'undefined'){ store.dispatch(uiActions.createNotification('Failed to load playlist tracks','bad')) } else { - var tracks_uris = helpers.asURIs(response.tracks) + var tracks_uris = helpers.arrayOf('uri',response.tracks) store.dispatch(mopidyActions.playURIs(tracks_uris, action.uri)) } }) @@ -582,7 +582,7 @@ const MopidyMiddleware = (function(){ .then( response => { // drop in our URI list - var playlist_uris = helpers.asURIs(response) + var playlist_uris = helpers.arrayOf('uri',response) store.dispatch({ type: 'LIBRARY_PLAYLISTS_LOADED', uris: playlist_uris }); @@ -645,7 +645,7 @@ const MopidyMiddleware = (function(){ case 'MOPIDY_RESOLVE_PLAYLIST_TRACKS': var tracks = Object.assign([], action.tracks) - var uris = helpers.asURIs(tracks) + var uris = helpers.arrayOf('uri',tracks) instruct( socket, store, 'library.lookup', { uris: uris } ) .then( response => { @@ -839,7 +839,7 @@ const MopidyMiddleware = (function(){ .then( response => { if (response.length <= 0) return - var uris = helpers.asURIs(response) + var uris = helpers.arrayOf('uri',response) store.dispatch({ type: 'MOPIDY_GET_ALBUMS', @@ -964,7 +964,7 @@ const MopidyMiddleware = (function(){ }); store.dispatch({ type: 'LOCAL_ARTISTS_LOADED', - uris: helpers.asURIs(response) + uris: helpers.arrayOf('uri',response) }); }) break; @@ -999,7 +999,7 @@ const MopidyMiddleware = (function(){ (response ? response[0].artists[0] : {}), { is_mopidy: true, - albums_uris: helpers.asURIs(albums), + albums_uris: helpers.arrayOf('uri',albums), tracks: response.slice(0,10) } ) diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js index 9a0faf5c..ab9bbf73 100755 --- a/src/js/services/spotify/actions.js +++ b/src/js/services/spotify/actions.js @@ -334,7 +334,7 @@ export function getFeaturedPlaylists(){ type: 'SPOTIFY_FEATURED_PLAYLISTS_LOADED', data: { message: response.message, - playlists: helpers.asURIs(response.playlists.items) + playlists: helpers.arrayOf('uri',response.playlists.items) } }); }); @@ -471,11 +471,11 @@ export function getSearchResults(query, type = 'album,artist,playlist,track', li dispatch({ type: 'SEARCH_RESULTS_LOADED', - playlists_uris: helpers.asURIs(playlists), + playlists_uris: helpers.arrayOf('uri',playlists), playlists_more: response.playlists.next, - artists_uris: helpers.asURIs(response.artists.items), + artists_uris: helpers.arrayOf('uri',response.artists.items), artists_more: response.artists.next, - albums_uris: helpers.asURIs(response.albums.items), + albums_uris: helpers.arrayOf('uri',response.albums.items), albums_more: response.albums.next, tracks: response.tracks.items, tracks_more: response.tracks.next @@ -765,7 +765,7 @@ export function getRecommendations(uris = [], limit = 20){ seeds_uris: uris, tracks: response.tracks, artists_uris: artists_uris, - albums_uris: helpers.asURIs(albums) + albums_uris: helpers.arrayOf('uri',albums) }) }) } @@ -833,7 +833,7 @@ export function getArtist(uri, full = false){ type: 'ARTISTS_LOADED', artists: response.artists }); - Object.assign(artist, { related_artists_uris: helpers.asURIs(response.artists) }); + Object.assign(artist, { related_artists_uris: helpers.arrayOf('uri',response.artists) }); }) ) } @@ -888,7 +888,7 @@ export function getArtists( uris ){ album: artist.albums[i] }); } - artist.albums = helpers.asURIs(artist.albums) + artist.albums = helpers.arrayOf('uri',artist.albums) artist.albums_more = artist.albums.next dispatch({ type: 'ARTIST_LOADED', @@ -919,14 +919,14 @@ export function playArtistTopTracks(uri){ // Do we have this artist (and their tracks) in our index already? if (typeof(artists[uri]) !== 'undefined' && typeof(artists[uri].tracks) !== 'undefined'){ - const uris = helpers.asURIs(artists[uri].tracks) + const uris = helpers.arrayOf('uri',artists[uri].tracks) dispatch(mopidyActions.playURIs(uris, uri)) // We need to load the artist's top tracks first } else { sendRequest( dispatch, getState, 'artists/'+ helpers.getFromUri('artistid', uri) +'/top-tracks?country='+getState().spotify.country ) .then( response => { - const uris = helpers.asURIs(response.tracks) + const uris = helpers.arrayOf('uri',response.tracks) dispatch(mopidyActions.playURIs(uris, uri)) }) } @@ -1013,7 +1013,7 @@ export function getAlbum( uri ){ {}, response, { - artists_uris: helpers.asURIs(response.artists), + artists_uris: helpers.arrayOf('uri',response.artists), tracks: response.tracks.items, tracks_more: response.tracks.next, tracks_total: response.tracks.total diff --git a/src/js/services/spotify/middleware.js b/src/js/services/spotify/middleware.js index d3c9f9f9..7c46ed8f 100755 --- a/src/js/services/spotify/middleware.js +++ b/src/js/services/spotify/middleware.js @@ -94,7 +94,7 @@ const SpotifyMiddleware = (function(){ }); store.dispatch({ type: 'NEW_RELEASES_LOADED', - uris: helpers.asURIs(action.data.albums.items), + uris: helpers.arrayOf('uri',action.data.albums.items), more: action.data.albums.next, total: action.data.albums.total }); @@ -108,7 +108,7 @@ const SpotifyMiddleware = (function(){ store.dispatch({ type: 'ARTIST_ALBUMS_LOADED', key: action.key, - uris: helpers.asURIs(action.data.items), + uris: helpers.arrayOf('uri',action.data.items), more: action.data.next, total: action.data.total }); @@ -139,7 +139,7 @@ const SpotifyMiddleware = (function(){ store.dispatch({ type: 'USER_PLAYLISTS_LOADED', key: action.key, - uris: helpers.asURIs(playlists), + uris: helpers.arrayOf('uri',playlists), more: action.data.next, total: action.data.total }); @@ -170,7 +170,7 @@ const SpotifyMiddleware = (function(){ store.dispatch({ type: 'CATEGORY_PLAYLISTS_LOADED', key: action.key, - uris: helpers.asURIs(playlists), + uris: helpers.arrayOf('uri',playlists), more: action.data.playlists.next, total: action.data.playlists.total }); @@ -202,7 +202,7 @@ const SpotifyMiddleware = (function(){ store.dispatch({ type: 'LIBRARY_PLAYLISTS_LOADED', - uris: helpers.asURIs(playlists) + uris: helpers.arrayOf('uri',playlists) }); break @@ -225,7 +225,7 @@ const SpotifyMiddleware = (function(){ }); store.dispatch({ type: 'LIBRARY_ARTISTS_LOADED', - uris: helpers.asURIs(artists), + uris: helpers.arrayOf('uri',artists), more: action.data.artists.next, total: action.data.artists.total }); @@ -256,7 +256,7 @@ const SpotifyMiddleware = (function(){ store.dispatch({ type: 'LIBRARY_ALBUMS_LOADED', - uris: helpers.asURIs(albums), + uris: helpers.arrayOf('uri',albums), more: action.data.next, total: action.data.total }); @@ -268,14 +268,14 @@ const SpotifyMiddleware = (function(){ type: 'ARTISTS_LOADED', artists: action.artists }) - action.artists_uris = helpers.asURIs(action.artists) + action.artists_uris = helpers.arrayOf('uri',action.artists) } if (action.tracks.length > 0){ store.dispatch({ type: 'TRACKS_LOADED', tracks: action.tracks }) - action.tracks_uris = helpers.asURIs(action.tracks) + action.tracks_uris = helpers.arrayOf('uri',action.tracks) } next(action) break @@ -305,7 +305,7 @@ const SpotifyMiddleware = (function(){ store.dispatch({ type: 'SEARCH_RESULTS_LOADED', - playlists_uris: helpers.asURIs(action.data.playlists.items), + playlists_uris: helpers.arrayOf('uri',action.data.playlists.items), playlists_more: action.data.playlists.next }); break @@ -319,7 +319,7 @@ const SpotifyMiddleware = (function(){ store.dispatch({ type: 'SEARCH_RESULTS_LOADED', - albums_uris: helpers.asURIs(action.data.albums.items), + albums_uris: helpers.arrayOf('uri',action.data.albums.items), albums_more: action.data.albums.next }); break @@ -344,7 +344,7 @@ const SpotifyMiddleware = (function(){ store.dispatch({ type: 'SEARCH_RESULTS_LOADED', - playlists_uris: helpers.asURIs(action.data.playlists.items), + playlists_uris: helpers.arrayOf('uri',action.data.playlists.items), playlists_more: action.data.playlists.next }); break diff --git a/src/scss/components/_lists.scss b/src/scss/components/_lists.scss index 1eb82e27..f0e9686f 100755 --- a/src/scss/components/_lists.scss +++ b/src/scss/components/_lists.scss @@ -232,7 +232,7 @@ .fa { position: absolute; top: 20px; - left: 13px; + left: 19px; pointer-events: none; color: $white; z-index: 1; @@ -247,7 +247,7 @@ height: 14px; position: absolute; top: 16px; - left: 10px; + left: 16px; } } @@ -333,10 +333,10 @@ } &.track-list { - .list-item.has-drag-zone { + .list-item.can-sort { padding: 8px 30px 8px 78px !important; } - .list-item:not(.has-drag-zone){ + .list-item:not(.can-sort){ padding: 8px 30px 8px 38px !important; } }