Drag-and-drop within tracklists
This commit is contained in:
@ -15,6 +15,7 @@ class Dragger extends React.Component{
|
||||
this.handleMouseUp = this.handleMouseUp.bind(this)
|
||||
|
||||
this.state = {
|
||||
active: false,
|
||||
position_x: 0,
|
||||
position_y: 0
|
||||
}
|
||||
@ -30,28 +31,33 @@ class Dragger extends React.Component{
|
||||
window.removeEventListener("mouseup", this.handleMouseUp, false);
|
||||
}
|
||||
|
||||
componentWillReceiveProps( nextProps ){
|
||||
if( this.props.dragger && this.props.dragger.dragging ){
|
||||
this.setState( nextProps.dragger )
|
||||
handleMouseMove(e){
|
||||
if( !this.props.dragger ) return null;
|
||||
|
||||
var threshold = 10
|
||||
if(
|
||||
e.clientX > this.props.dragger.start_x + threshold ||
|
||||
e.clientX < this.props.dragger.start_x - threshold ||
|
||||
e.clientY > this.props.dragger.start_y + threshold ||
|
||||
e.clientY < this.props.dragger.start_y - threshold ){
|
||||
|
||||
this.setState({
|
||||
position_x: e.clientX,
|
||||
position_y: e.clientY
|
||||
})
|
||||
|
||||
// if not already, activate
|
||||
if( !this.props.dragger.active ) this.props.uiActions.dragActive()
|
||||
}
|
||||
}
|
||||
|
||||
handleMouseMove(e){
|
||||
if( !this.props.dragger || !this.props.dragger.dragging ) return null;
|
||||
|
||||
this.setState({
|
||||
position_x: e.clientX,
|
||||
position_y: e.clientY
|
||||
})
|
||||
}
|
||||
|
||||
handleMouseUp(e){
|
||||
if( !this.props.dragger || !this.props.dragger.dragging ) return null;
|
||||
if( !this.props.dragger ) return null;
|
||||
this.props.uiActions.dragEnd( e )
|
||||
}
|
||||
|
||||
render(){
|
||||
if( !this.props.dragger || !this.props.dragger.dragging ) return null;
|
||||
if( !this.props.dragger || !this.props.dragger.active ) return null;
|
||||
|
||||
var style = {
|
||||
left: this.state.position_x,
|
||||
|
||||
@ -36,7 +36,7 @@ class Dropzones extends React.Component{
|
||||
}
|
||||
|
||||
handleMouseMove(e){
|
||||
if( !this.props.dragger || !this.props.dragger.dragging ) return null;
|
||||
if( !this.props.dragger || !this.props.dragger.active ) return null;
|
||||
this.props.uiActions.dragMove( e )
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ class Dropzones extends React.Component{
|
||||
}
|
||||
|
||||
render(){
|
||||
if( !this.props.dragger || !this.props.dragger.dragging ) return null
|
||||
if( !this.props.dragger || !this.props.dragger.active ) return null
|
||||
|
||||
return (
|
||||
<div className="dropzones">
|
||||
|
||||
@ -23,11 +23,14 @@ export default class Track extends React.Component{
|
||||
return this.props.handleDoubleClick(e);
|
||||
}
|
||||
|
||||
handleDragStart(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)
|
||||
}
|
||||
|
||||
this.props.handleDragStart(e)
|
||||
handleMouseUp(e){
|
||||
this.props.handleMouseUp(e)
|
||||
}
|
||||
|
||||
handleContextMenu(e){
|
||||
@ -51,8 +54,8 @@ export default class Track extends React.Component{
|
||||
return (
|
||||
<div
|
||||
className={className}
|
||||
draggable='true'
|
||||
onDragStart={ e => this.handleDragStart(e) }
|
||||
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) }>
|
||||
|
||||
@ -88,8 +88,16 @@ class TrackList extends React.Component{
|
||||
this.playTracks()
|
||||
}
|
||||
|
||||
handleDragStart(e, index){
|
||||
this.props.uiActions.dragStart( e, this.props.context, this.selectedTracks() )
|
||||
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 ){
|
||||
var indexes = this.props.dragger.victims_indexes
|
||||
this.props.uiActions.reorderTracks(this.props.context, indexes, index)
|
||||
}
|
||||
}
|
||||
|
||||
handleContextMenu(e, index){
|
||||
@ -173,7 +181,8 @@ class TrackList extends React.Component{
|
||||
track={track}
|
||||
handleDoubleClick={ e => self.handleDoubleClick(e, index)}
|
||||
handleClick={ e => self.handleClick(e, index)}
|
||||
handleDragStart={ e => self.handleDragStart(e, index)}
|
||||
handleMouseUp={ e => self.handleMouseUp(e, index)}
|
||||
handleMouseDown={ e => self.handleMouseDown(e, index)}
|
||||
handleContextMenu={ e => self.handleContextMenu(e, index)} />
|
||||
}
|
||||
)
|
||||
@ -192,6 +201,7 @@ class TrackList extends React.Component{
|
||||
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
return {
|
||||
dragger: state.ui.dragger,
|
||||
current_track: state.ui.current_track,
|
||||
context_menu: state.ui.context_menu
|
||||
}
|
||||
|
||||
@ -40,32 +40,45 @@ export function lazyLoading( start ){
|
||||
}
|
||||
}
|
||||
|
||||
export function dragStart( e, context, victims ){
|
||||
export function dragStart( e, context, victims, victims_indexes = false ){
|
||||
return {
|
||||
type: 'DRAG_START',
|
||||
context: context,
|
||||
victims: victims,
|
||||
position_x: e.clientX,
|
||||
position_y: e.clientY
|
||||
victims_indexes: victims_indexes,
|
||||
start_x: e.clientX,
|
||||
start_y: e.clientY
|
||||
}
|
||||
}
|
||||
|
||||
export function dragMove( e ){
|
||||
return {
|
||||
type: 'DRAG_MOVE',
|
||||
position_x: e.clientX,
|
||||
position_y: e.clientY,
|
||||
}
|
||||
}
|
||||
|
||||
export function dragCancel(){
|
||||
return { type: 'DRAG_CANCEL' }
|
||||
export function dragActive(){
|
||||
return { type: 'DRAG_ACTIVE' }
|
||||
}
|
||||
|
||||
export function dragEnd(){
|
||||
return { type: 'DRAG_END' }
|
||||
}
|
||||
|
||||
export function reorderTracks( context, indexes, destination_index ){
|
||||
console.log('uiActions.reorderTracks', context, indexes, destination_index)
|
||||
switch( context ){
|
||||
|
||||
case 'queue':
|
||||
return {
|
||||
type: 'MOPIDY_REORDER_TRACKLIST',
|
||||
indexes: indexes,
|
||||
destination_index: destination_index
|
||||
}
|
||||
|
||||
case 'editable-playlist':
|
||||
return {
|
||||
type: 'SPOTIFY_REORDER_TRACKLIST',
|
||||
indexes: indexes,
|
||||
destination_index: destination_index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function savePlaylist( uri, name, is_public = false ){
|
||||
switch( helpers.uriSource( uri ) ){
|
||||
|
||||
|
||||
@ -34,36 +34,22 @@ export default function reducer(ui = {}, action){
|
||||
return Object.assign({}, ui, {
|
||||
dragger: {
|
||||
dragging: true,
|
||||
active: false,
|
||||
context: action.context,
|
||||
victims: action.victims,
|
||||
position_x: action.position_x,
|
||||
position_y: action.position_y
|
||||
victims_indexes: action.victims_indexes,
|
||||
start_x: action.start_x,
|
||||
start_y: action.start_y
|
||||
}
|
||||
});
|
||||
|
||||
case 'DRAG_MOVE':
|
||||
var dragger = Object.assign({}, ui.dragger, {
|
||||
position_x: action.position_x,
|
||||
position_y: action.position_y
|
||||
})
|
||||
case 'DRAG_ACTIVE':
|
||||
var dragger = Object.assign({}, ui.dragger, { active: true })
|
||||
return Object.assign({}, ui, { dragger: dragger });
|
||||
|
||||
case 'DRAG_END':
|
||||
return Object.assign({}, ui, {
|
||||
dragger: {
|
||||
dragging: false,
|
||||
context: false,
|
||||
victims: false
|
||||
}
|
||||
});
|
||||
|
||||
case 'DRAG_CANCEL':
|
||||
return Object.assign({}, ui, {
|
||||
dragger: {
|
||||
dragging: false,
|
||||
context: false,
|
||||
victims: false
|
||||
}
|
||||
dragger: false
|
||||
});
|
||||
|
||||
|
||||
|
||||
@ -106,7 +106,7 @@ class App extends React.Component{
|
||||
|
||||
render(){
|
||||
var className = '';
|
||||
if( this.props.dragger && this.props.dragger.dragging ) className += ' dragging'
|
||||
if( this.props.dragger && this.props.dragger.active ) className += ' dragging'
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
|
||||
@ -60,6 +60,11 @@
|
||||
&.playing {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
:root .dragging &:hover {
|
||||
border-top: 3px solid $blue;
|
||||
margin-top: -3px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user