diff --git a/package.json b/package.json index fad5539..2ee2845 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "html-webpack-plugin": "2.29.0", "jest": "20.0.4", "lodash": "^4.17.4", + "lodash.flow": "^3.5.0", "object-assign": "4.1.1", "plyr": "^2.0.18", "postcss-flexbugs-fixes": "3.2.0", @@ -37,6 +38,8 @@ "raf": "3.4.0", "react": "^16.0.0", "react-dev-utils": "^4.2.1", + "react-dnd": "^5.0.0", + "react-dnd-html5-backend": "^5.0.1", "react-dom": "^16.0.0", "react-fontawesome": "^1.6.1", "react-redux": "^5.0.6", diff --git a/src/actions/nowPlayingActions.js b/src/actions/nowPlayingActions.js index d365bb9..3ff8917 100644 --- a/src/actions/nowPlayingActions.js +++ b/src/actions/nowPlayingActions.js @@ -3,6 +3,7 @@ import api from '../utils/api'; export const actionType = { songAdd: 'SONG_ADD', songRemove: 'SONG_REMOVE', + songSwap: 'SONG_SWAP', playNext: 'PLAY_NEXT', playedNext: 'PLAYED_NEXT', getSuggestions: 'GET_SUGGESTIONS' @@ -12,6 +13,10 @@ export function addSong(song) { return dispatch => dispatch({type: actionType.songAdd, song}); } +export function swapSong(dragIndex, hoverIndex) { + return dispatch => dispatch({type: actionType.songSwap, dragIndex: dragIndex, hoverIndex: hoverIndex}); +} + export function removeSong(song) { return dispatch => dispatch({type: actionType.songRemove, song}); } diff --git a/src/components/sideBar/index.js b/src/components/sideBar/index.js index 8da5076..7ce4a25 100644 --- a/src/components/sideBar/index.js +++ b/src/components/sideBar/index.js @@ -1,9 +1,11 @@ import React from 'react'; - import MiniCardList from "./miniCard/miniCardList"; -import './static/css/index.css' +import './static/css/index.css'; +import {DragDropContext} from 'react-dnd'; +import HTML5Backend from 'react-dnd-html5-backend'; + -export default class SideBar extends React.Component { +class SideBar extends React.Component { componentWillReceiveProps(nextProps) { if (nextProps.dispatchNext) { @@ -18,6 +20,11 @@ export default class SideBar extends React.Component { } } + moveCard = (dragIndex, hoverIndex) => { + console.log(dragIndex + " "+ hoverIndex); + this.props.swapSong(dragIndex, hoverIndex); + } + playSong(video) { this.props.playSong(video); this.props.playedNext(video); @@ -44,7 +51,8 @@ export default class SideBar extends React.Component {
+ removeSong = {this.props.removeSong} + moveCard = {this.moveCard}/>
@@ -52,3 +60,5 @@ export default class SideBar extends React.Component { ) } } + +export default DragDropContext(HTML5Backend)(SideBar) ; \ No newline at end of file diff --git a/src/components/sideBar/miniCard/miniCard.js b/src/components/sideBar/miniCard/miniCard.js index d0137f6..b24ea6a 100644 --- a/src/components/sideBar/miniCard/miniCard.js +++ b/src/components/sideBar/miniCard/miniCard.js @@ -2,7 +2,65 @@ import React from 'react'; import './static/css/minicard.css'; -export default class MiniCard extends React.Component { +import { DragSource, DropTarget } from 'react-dnd'; +import { findDOMNode } from 'react-dom'; +import flow from 'lodash/flow' + +const cardSource = { + beginDrag(props) { + console.log(props.song); + console.log(props.song.id + " "+props.index); + if(props.name === 'queue') + { + return { + id: props.song.id, + index: props.index, + } + } + + return ; + } +} + +const cardTarget = { + hover(props, monitor, component) { + if (!component) { + return null + } + const dragIndex = monitor.getItem().index + const hoverIndex = props.index + + // Don't replace items with themselves + if (dragIndex === hoverIndex) { + return + } + + const hoverBoundingRect = (findDOMNode( + component, + )).getBoundingClientRect() + + const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2 + + const clientOffset = monitor.getClientOffset() + + const hoverClientY = (clientOffset).y - hoverBoundingRect.top + + if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) { + return + } + + if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) { + return + } + + props.moveCard(dragIndex, hoverIndex) + + monitor.getItem().index = hoverIndex + }, +} + + +class MiniCard extends React.Component { play() { this.props.playSong(this.props.song); } @@ -16,6 +74,9 @@ export default class MiniCard extends React.Component { } render() { + const {isDragging, connectDragSource,connectDropTarget,} = this.props; + + const opacity = isDragging ? 0.5 : 1; const MAX_TITLE_LENGTH = 24; @@ -28,7 +89,11 @@ export default class MiniCard extends React.Component { console.log(this.props.name); return ( -
+ connectDragSource && + connectDropTarget && + connectDragSource( + connectDropTarget( +
IMG @@ -46,6 +111,18 @@ export default class MiniCard extends React.Component {
+ ), + ) ) } } + +export default flow(DragSource('card', + cardSource, + (connect, monitor) => ({ + connectDragSource: connect.dragSource(), + isDragging: monitor.isDragging(), + }),),DropTarget('card', cardTarget, (connect) => ({ + connectDropTarget: connect.dropTarget(), +}) + ))(MiniCard); \ No newline at end of file diff --git a/src/components/sideBar/miniCard/miniCardList.js b/src/components/sideBar/miniCard/miniCardList.js index 3b06da0..086a2ed 100644 --- a/src/components/sideBar/miniCard/miniCardList.js +++ b/src/components/sideBar/miniCard/miniCardList.js @@ -2,9 +2,21 @@ import React from 'react'; import MiniCard from "./miniCard"; -export default class MiniCardList extends React.Component { + +class MiniCardList extends React.Component { + + state = { + updatedSongList : false, + } + + swapCard = (dragIndex, hoverIndex) => { + this.props.moveCard(dragIndex, hoverIndex); + this.setState({updatedSongList : !this.state.updatedSongList}); + } + render() { - return this.props.songs.map(song => { + console.log(this.props.songs); + return this.props.songs.map( (song, i) => { if (this.props.currentSong && song.id === this.props.currentSong.id) { return }); } } + +export default MiniCardList; diff --git a/src/containers/sideBarContainer.js b/src/containers/sideBarContainer.js index 40925ab..e6f4ceb 100644 --- a/src/containers/sideBarContainer.js +++ b/src/containers/sideBarContainer.js @@ -1,7 +1,7 @@ import {connect} from 'react-redux'; import Sidebar from '../components/sideBar'; -import {removeSong, playedNext, addSong} from "../actions/nowPlayingActions"; +import {removeSong, playedNext, addSong, swapSong} from "../actions/nowPlayingActions"; import {playSong} from "../actions/playerActions"; function mapStateToProps(state) { @@ -18,6 +18,7 @@ function mapStateToProps(state) { export default connect( mapStateToProps, { + swapSong: swapSong, removeSong: removeSong, playedNext: playedNext, playSong: playSong, diff --git a/src/index.js b/src/index.js index db7d2a5..6c6da65 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; import {createStore, compose, applyMiddleware} from 'redux'; import thunk from 'redux-thunk'; - import Root from './root'; import registerServiceWorker from './registerServiceWorker'; import reducers from './reducers'; diff --git a/src/reducers/nowPlayingReducer.js b/src/reducers/nowPlayingReducer.js index 8587bb8..6d36bad 100644 --- a/src/reducers/nowPlayingReducer.js +++ b/src/reducers/nowPlayingReducer.js @@ -1,7 +1,6 @@ import {actionType} from "../actions/nowPlayingActions"; import {removeDuplicateSongs} from "../utils/removeDuplicates"; import {anyCommonSong, removeDuplicateIn, songInArray} from '../utils/songSearchUtils'; - const initialState = {nextSongs: [], suggestedSongs: [], dispatchNext: false, previousSongs: []}; export function nowPlaying(state = initialState, action) { @@ -23,6 +22,17 @@ export function nowPlaying(state = initialState, action) { case actionType.playNext: return {...state, dispatchNext: true}; + case actionType.songSwap: + const dragCard = state.nextSongs[action.dragIndex]; + const hoverCard = state.nextSongs[action.hoverIndex]; + let tmp = state.nextSongs; + tmp.splice(action.dragIndex,1,hoverCard); + console.log(tmp); + let anothertmp = tmp; + anothertmp.splice(action.hoverIndex,1,dragCard); + console.log(anothertmp); + return {...state, nextSongs: anothertmp}; + case actionType.playedNext: prev = state.previousSongs.slice(0); prev.push(action.song);