Dragging vs context menu vs selection vs ctrl
This commit is contained in:
@ -12,21 +12,15 @@ export default class Track extends React.Component{
|
||||
super(props);
|
||||
}
|
||||
|
||||
handleClick(e){
|
||||
var target = $(e.target);
|
||||
if( !target.is('a') && target.closest('a').length <= 0 ){
|
||||
this.props.handleClick(e);
|
||||
}
|
||||
}
|
||||
|
||||
handleDoubleClick(e){
|
||||
return this.props.handleDoubleClick(e);
|
||||
}
|
||||
|
||||
handleMouseDown(e){
|
||||
// if we're not selected, perform click behavior [first] << this is assumed
|
||||
if( !this.props.track.selected ) this.handleClick(e)
|
||||
this.props.handleMouseDown(e)
|
||||
var target = $(e.target);
|
||||
if( !target.is('a') && target.closest('a').length <= 0 ){
|
||||
this.props.handleMouseDown(e);
|
||||
}
|
||||
}
|
||||
|
||||
handleMouseUp(e){
|
||||
@ -35,11 +29,6 @@ export default class Track extends React.Component{
|
||||
|
||||
handleContextMenu(e){
|
||||
e.preventDefault();
|
||||
|
||||
// trigger a regular click event
|
||||
if( !this.props.track.selected ) this.handleClick(e);
|
||||
|
||||
// notify our tracklist
|
||||
this.props.handleContextMenu(e);
|
||||
}
|
||||
|
||||
@ -56,12 +45,11 @@ export default class Track extends React.Component{
|
||||
className={className}
|
||||
onMouseDown={ e => this.handleMouseDown(e) }
|
||||
onMouseUp={ e => this.handleMouseUp(e) }
|
||||
onClick={ e => this.handleClick(e) }
|
||||
onDoubleClick={ e => this.handleDoubleClick(e) }
|
||||
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.uri }
|
||||
{ track.name ? track.name : <span className="grey-text">{track.uri}</span> }
|
||||
</span>
|
||||
<span className="col artists">
|
||||
{ track.artists ? <ArtistSentence artists={track.artists} /> : '-' }
|
||||
|
||||
@ -48,9 +48,55 @@ class TrackList extends React.Component{
|
||||
}
|
||||
}
|
||||
|
||||
handleClick( e, index ){
|
||||
handleDoubleClick(e, index){
|
||||
if( this.props.context_menu.show ) this.props.uiActions.hideContextMenu()
|
||||
this.playTracks()
|
||||
}
|
||||
|
||||
handleMouseDown(e, index){
|
||||
if( this.props.context_menu.show ) this.props.uiActions.hideContextMenu()
|
||||
|
||||
if( !this.state.tracks[index].selected && !this.isRightClick(e) && !e.ctrlKey ) this.toggleTrackSelections(e, index)
|
||||
|
||||
var selected_tracks = this.selectedTracks()
|
||||
this.props.uiActions.dragStart( e, this.props.context, selected_tracks, this.tracksIndexes(selected_tracks) )
|
||||
}
|
||||
|
||||
handleMouseUp(e, index){
|
||||
|
||||
// right-clicking on an un-highlighted track
|
||||
if( !this.state.tracks[index].selected && this.isRightClick(e) ){
|
||||
this.toggleTrackSelections(e, index)
|
||||
|
||||
// selected track, regular click
|
||||
}else if( this.state.tracks[index].selected && !this.isRightClick(e) ){
|
||||
this.toggleTrackSelections(e, index)
|
||||
|
||||
// ctrl key
|
||||
}else if( e.ctrlKey ){
|
||||
this.toggleTrackSelections(e, index)
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleContextMenu(e, index){
|
||||
var selected_tracks = this.selectedTracks()
|
||||
var data = {
|
||||
selected_tracks: selected_tracks,
|
||||
selected_tracks_indexes: this.tracksIndexes( selected_tracks )
|
||||
}
|
||||
this.props.uiActions.showContextMenu( e, this.props.context, data )
|
||||
}
|
||||
|
||||
toggleTrackSelections(e, index){
|
||||
var tracks = this.state.tracks
|
||||
|
||||
if( e.ctrlKey ){
|
||||
@ -83,34 +129,12 @@ class TrackList extends React.Component{
|
||||
this.setState({ tracks: tracks, lastSelectedTrack: index })
|
||||
}
|
||||
|
||||
handleDoubleClick(e, index){
|
||||
if( this.props.context_menu.show ) this.props.uiActions.hideContextMenu()
|
||||
this.playTracks()
|
||||
}
|
||||
|
||||
handleMouseDown(e, index){
|
||||
var selected_tracks = this.selectedTracks()
|
||||
this.props.uiActions.dragStart( e, this.props.context, selected_tracks, this.tracksIndexes(selected_tracks) )
|
||||
}
|
||||
|
||||
handleMouseUp(e, index){
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleContextMenu(e, index){
|
||||
var selected_tracks = this.selectedTracks()
|
||||
var data = {
|
||||
selected_tracks: selected_tracks,
|
||||
selected_tracks_indexes: this.tracksIndexes( selected_tracks )
|
||||
}
|
||||
this.props.uiActions.showContextMenu( e, this.props.context, data )
|
||||
isRightClick(e){
|
||||
if( 'which' in e )
|
||||
return e.which == 3
|
||||
if( 'button' in e )
|
||||
return e.button == 2
|
||||
return false
|
||||
}
|
||||
|
||||
keyifyTracks( tracks ){
|
||||
|
||||
@ -12,7 +12,10 @@ 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)
|
||||
var actions_to_log = null
|
||||
//actions_to_log = 'SPOTIFY'
|
||||
//actions_to_log = 'MOPIDY'
|
||||
if( action.type.startsWith(actions_to_log) ) console.log(action)
|
||||
|
||||
switch( action.type ){
|
||||
|
||||
|
||||
@ -210,6 +210,15 @@ const MopidyMiddleware = (function(){
|
||||
})
|
||||
break;
|
||||
|
||||
case 'MOPIDY_CREATE_PLAYLIST':
|
||||
instruct( socket, store, 'playlists.create', { name: action.name, uri_scheme: action.scheme })
|
||||
.then( response => {
|
||||
|
||||
// re-load our global playlists
|
||||
store.dispatch({ type: 'MOPIDY_PLAYLISTS' });
|
||||
});
|
||||
break
|
||||
|
||||
case 'MOPIDY_PLAYLIST':
|
||||
store.dispatch({ type: 'MOPIDY_PLAYLIST_LOADED', data: false });
|
||||
instruct( socket, store, 'playlists.lookup', action.data )
|
||||
@ -227,13 +236,13 @@ const MopidyMiddleware = (function(){
|
||||
)
|
||||
|
||||
// tracks? get the full track objects
|
||||
if( playlist.tracks.length > 0 ) store.dispatch({ type: 'MOPIDY_FETCH_PLAYLIST_TRACKS', tracks: playlist.tracks })
|
||||
if( playlist.tracks.length > 0 ) store.dispatch({ type: 'MOPIDY_PLAYLIST_TRACKS', tracks: playlist.tracks })
|
||||
|
||||
store.dispatch({ type: 'MOPIDY_PLAYLIST_LOADED', data: playlist })
|
||||
})
|
||||
break;
|
||||
|
||||
case 'MOPIDY_FETCH_PLAYLIST_TRACKS':
|
||||
case 'MOPIDY_PLAYLIST_TRACKS':
|
||||
var tracks = Object.assign([], action.tracks)
|
||||
var uris = [];
|
||||
for( var i = 0; i < tracks.length; i++ ){
|
||||
@ -315,15 +324,6 @@ const MopidyMiddleware = (function(){
|
||||
});
|
||||
break
|
||||
|
||||
case 'MOPIDY_CREATE_PLAYLIST':
|
||||
instruct( socket, store, 'playlists.create', { name: action.name, uri_scheme: action.scheme })
|
||||
.then( response => {
|
||||
|
||||
// re-load our global playlists
|
||||
store.dispatch({ type: 'MOPIDY_PLAYLISTS' });
|
||||
});
|
||||
break
|
||||
|
||||
case 'MOPIDY_SAVE_PLAYLIST':
|
||||
instruct( socket, store, 'playlists.lookup', { uri: action.uri })
|
||||
.then( response => {
|
||||
@ -376,7 +376,7 @@ const MopidyMiddleware = (function(){
|
||||
.then( response => {
|
||||
|
||||
// and now re-render our full track references
|
||||
store.dispatch({ type: 'MOPIDY_FETCH_PLAYLIST_TRACKS', tracks: playlist.tracks })
|
||||
store.dispatch({ type: 'MOPIDY_PLAYLIST_TRACKS', tracks: playlist.tracks })
|
||||
})
|
||||
});
|
||||
break
|
||||
|
||||
@ -641,3 +641,20 @@ 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
|
||||
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 } )
|
||||
.then( response => {
|
||||
dispatch({
|
||||
type: 'PLAYLIST_TRACKS_REORDERED',
|
||||
range_start: range_start,
|
||||
range_length: range_length,
|
||||
to_index: to_index,
|
||||
snapshot_id: response.snapshot_id
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -52,6 +52,16 @@ const SpotifyMiddleware = (function(){
|
||||
break
|
||||
|
||||
|
||||
case 'SPOTIFY_REORDER_PLAYLIST_TRACKS':
|
||||
|
||||
if( !store.getState().spotify.authorized ){
|
||||
alert('Must be logged in to Spotify to do this')
|
||||
return
|
||||
}
|
||||
store.dispatch( actions.reorderPlaylistTracks( action.uri, action.indexes, action.to_index ))
|
||||
break
|
||||
|
||||
|
||||
case 'SPOTIFY_SAVE_PLAYLIST':
|
||||
|
||||
if( !store.getState().spotify.authorized ){
|
||||
|
||||
@ -59,15 +59,17 @@ export function dragEnd(){
|
||||
return { type: 'DRAG_END' }
|
||||
}
|
||||
|
||||
export function reorderPlaylistTracks( uri, indexes, to_index ){
|
||||
export function reorderPlaylistTracks( uri, indexes, to_index, snapshot_id = false ){
|
||||
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
|
||||
to_index: to_index,
|
||||
snapshot_id: snapshot_id
|
||||
}
|
||||
|
||||
case 'm3u':
|
||||
|
||||
@ -233,13 +233,13 @@ 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 })
|
||||
return Object.assign({}, ui, { playlist: playlist });
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Library Playlists
|
||||
|
||||
@ -74,7 +74,7 @@ class Playlist extends React.Component{
|
||||
}
|
||||
|
||||
reorderTracks( indexes, index ){
|
||||
this.props.uiActions.reorderPlaylistTracks( this.props.playlist.uri, indexes, index )
|
||||
this.props.uiActions.reorderPlaylistTracks( this.props.playlist.uri, indexes, index, this.props.playlist.snapshot_id )
|
||||
}
|
||||
|
||||
removeTracks( tracks_indexes ){
|
||||
|
||||
Reference in New Issue
Block a user