diff --git a/src/actions/index.js b/src/actions/index.js index 17ae142..869cb41 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -6,7 +6,7 @@ import { fetchActivitiesByGenre } from './browse'; import { like } from './track'; import { follow } from './following'; import { setToggle } from './toggle'; -import { activateTrack, activateIteratedTrack, addTrackToPlaylist, removeTrackFromPlaylist, clearPlaylist, togglePlayTrack } from './player'; +import { activateTrack, activateIteratedTrack, addTrackToPlaylist, removeTrackFromPlaylist, clearPlaylist, togglePlayTrack, toggleShuffleMode } from './player'; import { openComments, fetchComments } from './comments'; import { filterDuration, filterName } from './filter'; import { sortStream } from './sort'; @@ -34,5 +34,6 @@ export { fetchComments, filterDuration, filterName, - sortStream + sortStream, + toggleShuffleMode }; diff --git a/src/actions/player/index.js b/src/actions/player/index.js index e145277..94099e5 100644 --- a/src/actions/player/index.js +++ b/src/actions/player/index.js @@ -45,6 +45,13 @@ function emptyPlaylist() { }; } +function setIsInShuffleMode(isInShuffleMode) { + return { + type: actionTypes.CHANGE_SHUFFLE_MODE, + isInShuffleMode + }; +} + export const clearPlaylist = () => (dispatch) => { dispatch(emptyPlaylist()); dispatch(deactivateTrack()); @@ -90,12 +97,32 @@ function getIteratedTrack(playlist, currentActiveTrackId, iterate) { return playlist[index + iterate]; } +function getRandomTrack(playlist, currentActiveTrackId) { + const index = findIndex(isSameTrack(currentActiveTrackId), playlist); + function getRandomIndex() { + const randNum = Math.floor(Math.random() * playlist.length); + if (randNum === index) { + return getRandomIndex(); + } else { + return randNum; + } + } + return playlist[getRandomIndex()]; +} + export const activateIteratedTrack = (currentActiveTrackId, iterate) => (dispatch, getState) => { const playlist = getState().player.playlist; const nextActiveTrackId = getIteratedTrack(playlist, currentActiveTrackId, iterate); + const randomActiveTrackId = getRandomTrack(playlist, currentActiveTrackId); + const shuffleMode = getState().player.shuffleMode; + // const previousActiveTrackId = getState().player.activeTrackId; + - if (nextActiveTrackId) { + if (nextActiveTrackId && shuffleMode === false) { dispatch(activateTrack(nextActiveTrackId)); + } else if (shuffleMode === true) { + dispatch(activateTrack(randomActiveTrackId)); + // dispatch(removeTrackFromPlaylist(previousActiveTrackId)); } else { dispatch(togglePlayTrack(false)); } @@ -118,3 +145,7 @@ export const removeTrackFromPlaylist = (track) => (dispatch, getState) => { dispatch(removeFromPlaylist(track.id)); }; + +export const toggleShuffleMode = (isInShuffleMode) => (dispatch) => { + dispatch(setIsInShuffleMode(isInShuffleMode)); +}; diff --git a/src/components/Player/index.js b/src/components/Player/index.js index 48046ac..6e8152b 100644 --- a/src/components/Player/index.js +++ b/src/components/Player/index.js @@ -30,10 +30,12 @@ class Player extends React.Component { isPlaying, entities, playlist, + shuffleMode, onSetToggle, onActivateIteratedTrack, onLike, - onTogglePlayTrack + onTogglePlayTrack, + onSetShuffleMode } = this.props; if (!activeTrackId) { return null; } @@ -57,6 +59,13 @@ class Player extends React.Component { } ); + const shuffleClass = classNames( + 'fa fa-random', + { + randomSelected: shuffleMode + } + ); + return (
@@ -82,6 +91,11 @@ class Player extends React.Component { {playlist.length}
+
+ onSetShuffleMode(shuffleMode)}> + + +
{ currentUser ? @@ -115,6 +129,7 @@ function mapStateToProps(state) { isPlaying: state.player.isPlaying, entities: state.entities, playlist: state.player.playlist, + shuffleMode: state.player.shuffleMode }; } @@ -123,7 +138,8 @@ function mapDispatchToProps(dispatch) { onTogglePlayTrack: bindActionCreators(actions.togglePlayTrack, dispatch), onSetToggle: bindActionCreators(actions.setToggle, dispatch), onActivateIteratedTrack: bindActionCreators(actions.activateIteratedTrack, dispatch), - onLike: bindActionCreators(actions.like, dispatch) + onLike: bindActionCreators(actions.like, dispatch), + onSetShuffleMode: bindActionCreators(actions.toggleShuffleMode, dispatch), }; } @@ -136,7 +152,8 @@ Player.propTypes = { onTogglePlayTrack: React.PropTypes.func, onSetToggle: React.PropTypes.func, onActivateIteratedTrack: React.PropTypes.func, - onLike: React.PropTypes.func + onLike: React.PropTypes.func, + onSetShuffleMode: React.PropTypes.func, }; const PlayerContainer = connect(mapStateToProps, mapDispatchToProps)(Player); diff --git a/src/constants/actionTypes.js b/src/constants/actionTypes.js index 6567dd7..e16166c 100644 --- a/src/constants/actionTypes.js +++ b/src/constants/actionTypes.js @@ -25,6 +25,7 @@ export const SET_IS_PLAYING = 'SET_IS_PLAYING'; export const SET_TRACK_IN_PLAYLIST = 'SET_TRACK_IN_PLAYLIST'; export const REMOVE_TRACK_FROM_PLAYLIST = 'REMOVE_TRACK_FROM_PLAYLIST'; export const RESET_PLAYLIST = 'RESET_PLAYLIST'; +export const CHANGE_SHUFFLE_MODE = 'CHANGE_SHUFFLE_MODE'; export const SET_IS_OPEN_PLAYLIST = 'SET_IS_OPEN_PLAYLIST'; diff --git a/src/reducers/player/index.js b/src/reducers/player/index.js index afa2b17..60ff249 100644 --- a/src/reducers/player/index.js +++ b/src/reducers/player/index.js @@ -1,6 +1,7 @@ import * as actionTypes from '../../constants/actionTypes'; const initialState = { + shuffleMode: false, activeTrackId: null, isPlaying: false, playlist: [] @@ -20,6 +21,8 @@ export default function(state = initialState, action) { return removeTrackFromPlaylist(state, action.trackId); case actionTypes.RESET_PLAYLIST: return emptyPlaylist(state); + case actionTypes.CHANGE_SHUFFLE_MODE: + return setShuffleMode(state); } return state; } @@ -56,3 +59,11 @@ function removeTrackFromPlaylist(state, trackId) { function emptyPlaylist(state) { return { ...state, playlist: [] }; } + +function setShuffleMode(state) { + if (state.shuffleMode === false) { + return { ...state, shuffleMode: true }; + } else { + return { ...state, shuffleMode: false }; + } +} diff --git a/src/stores/configureStore.js b/src/stores/configureStore.js index 7e37f64..bb24154 100644 --- a/src/stores/configureStore.js +++ b/src/stores/configureStore.js @@ -10,5 +10,5 @@ const router = routerMiddleware(browserHistory); const createStoreWithMiddleware = applyMiddleware(thunk, router, mixpanel)(createStore); export default function configureStore(initialState) { - return createStoreWithMiddleware(rootReducer, initialState); + return createStoreWithMiddleware(rootReducer, initialState, window.devToolsExtension && window.devToolsExtension()); } diff --git a/styles/components/player.scss b/styles/components/player.scss index c89f948..4da82e1 100644 --- a/styles/components/player.scss +++ b/styles/components/player.scss @@ -52,4 +52,8 @@ } -} \ No newline at end of file + .randomSelected{ + color: $mainColor; + } + +}