diff --git a/src/js/bootstrap.js b/src/js/bootstrap.js
index 5901fe30..e0693d88 100755
--- a/src/js/bootstrap.js
+++ b/src/js/bootstrap.js
@@ -24,20 +24,21 @@ var initialState = {
},
spotify: {
country: 'NZ',
- locale: 'en_NZ'
+ locale: 'en_NZ',
+ me: false
}
};
// if we've got a stored version of mopidy state, load and merge
if( localStorage.getItem('mopidy') ){
var storedMopidy = JSON.parse( localStorage.getItem('mopidy') );
- Object.assign(initialState, { mopidy: storedMopidy } );
+ initialState.mopidy = Object.assign(initialState.mopidy, storedMopidy );
}
// if we've got a stored version of spotify state, load and merge
if( localStorage.getItem('spotify') ){
var storedSpotify = JSON.parse( localStorage.getItem('spotify') );
- Object.assign(initialState, { spotify: storedSpotify } );
+ initialState.spotify = Object.assign(initialState.spotify, storedSpotify );
}
let store = createStore(
diff --git a/src/js/components/SpotifyAuthenticationFrame.js b/src/js/components/SpotifyAuthenticationFrame.js
index 28557396..ce6a45b4 100755
--- a/src/js/components/SpotifyAuthenticationFrame.js
+++ b/src/js/components/SpotifyAuthenticationFrame.js
@@ -24,11 +24,22 @@ class SpotifyAuthenticationFrame extends React.Component{
if( !/^https?:\/\/jamesbarnsley\.co\.nz/.test(event.origin) ) return false;
var data = JSON.parse(event.data);
- self.props.actions.completeAuthorization( data );
+ self.props.actions.authorizationGranted( data );
}, false);
}
+ renderMe(){
+ if( this.props.spotify.me ){
+ if( this.props.spotify.me.display_name ){
+ return Logged in as { this.props.spotify.me.display_name }
+ }else{
+ return Logged in as { this.props.spotify.me.id }
+ }
+ }
+ return null;
+ }
+
renderAuthorizeButton(){
if( this.props.spotify.authorizing ){
return (
@@ -39,7 +50,10 @@ class SpotifyAuthenticationFrame extends React.Component{
);
}else if( this.props.spotify.authorized ){
return (
-
+
+
+ { this.renderMe() }
+
);
}else{
return (
diff --git a/src/js/components/TrackList.js b/src/js/components/TrackList.js
index 621cfc88..42412825 100755
--- a/src/js/components/TrackList.js
+++ b/src/js/components/TrackList.js
@@ -49,24 +49,24 @@ class TrackList extends React.Component{
this.setState({ tracks: tracks, lastSelectedTrack: index });
}
- handleDoubleClick( e, index ){
- var tracks = this.state.tracks;
- this.props.actions.changeTrack( tracks[index].tlid )
- }
-
- deleteSelected(){
-
+ selectedTracks(){
function isSelected( track ){
return ( typeof(track.selected) !== 'undefined' && track.selected );
}
+ return this.state.tracks.filter(isSelected)
+ }
- var selectedTracks = this.state.tracks.filter(isSelected)
- var selectedTracksTlids = [];
- for( var i = 0; i < selectedTracks.length; i++ ){
- selectedTracksTlids.push( selectedTracks[i].tlid )
- }
+ handleDoubleClick( e, index ){
+ var tracks = this.state.tracks;
+ this.props.playTrack( tracks[index] )
+ }
- this.props.actions.removeTracks( selectedTracksTlids )
+ playTracks(){
+ this.props.playTracks( this.selectedTracks() )
+ }
+
+ removeTracks(){
+ this.props.removeTracks( this.selectedTracks() )
}
componentWillReceiveProps( nextProps ){
@@ -100,7 +100,8 @@ class TrackList extends React.Component{
)
}
-
+
+
);
}
diff --git a/src/js/services/localstorage/middleware.js b/src/js/services/localstorage/middleware.js
index 87060bb7..0b82f463 100755
--- a/src/js/services/localstorage/middleware.js
+++ b/src/js/services/localstorage/middleware.js
@@ -5,6 +5,8 @@ const localstorageMiddleware = (function(){
* The actual middleware inteceptor
**/
return store => next => action => {
+
+ console.log(action)
// proceed as normal first
// this way, any reducers and middleware do their thing BEFORE we store our new state
@@ -28,12 +30,18 @@ const localstorageMiddleware = (function(){
localStorage.setItem('spotify', JSON.stringify(spotify));
break;
- case 'SPOTIFY_COMPLETE_AUTHORIZATION':
- var spotify = {
- authorized: true,
- access_token: action.data.access_token,
- refresh_token: action.data.refresh_token
- };
+ case 'SPOTIFY_AUTHORIZATION_COMPLETE':
+ var spotify = JSON.parse( localStorage.getItem('spotify') );
+ if( !spotify ) spotify = {};
+ console.log(spotify)
+ Object.assign(
+ spotify,{
+ authorized: true,
+ access_token: action.data.access_token,
+ refresh_token: action.data.refresh_token,
+ me: action.data.me
+ }
+ );
localStorage.setItem('spotify', JSON.stringify(spotify));
break;
}
diff --git a/src/js/services/mopidy/actions.js b/src/js/services/mopidy/actions.js
index e760311d..dccf9649 100755
--- a/src/js/services/mopidy/actions.js
+++ b/src/js/services/mopidy/actions.js
@@ -30,6 +30,14 @@ export function changeTrack( tlid ){
}
}
+export function playTracks( uris ){
+ return {
+ type: 'MOPIDY_PLAY_TRACKS',
+ call: 'tracklist.add',
+ value: { at_position: 0, uris: uris }
+ }
+}
+
export function removeTracks( tlids ){
return {
type: 'MOPIDY_REMOVE_TRACKS',
diff --git a/src/js/services/mopidy/middleware.js b/src/js/services/mopidy/middleware.js
index 2b02185b..6987ea87 100755
--- a/src/js/services/mopidy/middleware.js
+++ b/src/js/services/mopidy/middleware.js
@@ -128,6 +128,13 @@ const MopidyMiddleware = (function(){
instruct( socket, store, action.call, action.value )
break;
+ case 'MOPIDY_PLAY_TRACKS':
+ var callback = function(){
+ store.dispatch({ type: 'MOPIDY_TEST', model: 'yeah', data: {} })
+ }
+ instruct( socket, store, action.call, action.value, callback )
+ break;
+
// This action is irrelevant to us, pass it on to the next middleware
default:
return next(action);
diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js
index 4554c439..286ce1fd 100755
--- a/src/js/services/spotify/actions.js
+++ b/src/js/services/spotify/actions.js
@@ -22,9 +22,9 @@ export function removeAuthorization(){
}
}
-export function completeAuthorization( data ){
+export function authorizationGranted( data ){
return {
- type: 'SPOTIFY_COMPLETE_AUTHORIZATION',
+ type: 'SPOTIFY_AUTHORIZATION_GRANTED',
data: data
}
}
diff --git a/src/js/services/spotify/middleware.js b/src/js/services/spotify/middleware.js
index 63dd7e49..a3369a87 100755
--- a/src/js/services/spotify/middleware.js
+++ b/src/js/services/spotify/middleware.js
@@ -38,6 +38,15 @@ const SpotifyMiddleware = (function(){
switch(action.type){
+ case 'SPOTIFY_AUTHORIZATION_GRANTED':
+ sendRequest( action.data.access_token, 'me' )
+ .then( (response) => {
+ var data = action.data;
+ data.me = response;
+ store.dispatch({ type: 'SPOTIFY_AUTHORIZATION_COMPLETE', data: data })
+ });
+ break;
+
case 'SPOTIFY_LOAD_ALBUM':
store.dispatch({ type: 'SPOTIFY_ALBUM_LOADED', data: false })
diff --git a/src/js/services/spotify/reducer.js b/src/js/services/spotify/reducer.js
index 6a1c6bd0..73e6bd6d 100755
--- a/src/js/services/spotify/reducer.js
+++ b/src/js/services/spotify/reducer.js
@@ -8,11 +8,12 @@ export default function reducer(spotify = {}, action){
case 'SPOTIFY_START_AUTHORIZATION':
return Object.assign({}, spotify, { authorizing: true });
- case 'SPOTIFY_COMPLETE_AUTHORIZATION':
+ case 'SPOTIFY_AUTHORIZATION_COMPLETE':
return Object.assign({}, spotify, {
authorizing: false,
authorized: true,
- authorization: action.data,
+ authorization: action.data,
+ me: action.data.me,
token: action.data.access_token
});
@@ -20,7 +21,9 @@ export default function reducer(spotify = {}, action){
return Object.assign({}, spotify, {
authorizing: false,
authorization: false,
- authorized: false
+ authorized: false,
+ token: false,
+ me: false
});
case 'SPOTIFY_CONNECTED':
diff --git a/src/js/views/Album.js b/src/js/views/Album.js
index 3e6a4b72..4c89591f 100755
--- a/src/js/views/Album.js
+++ b/src/js/views/Album.js
@@ -5,6 +5,7 @@ import { bindActionCreators } from 'redux'
import TrackList from '../components/TrackList'
import * as spotifyActions from '../services/spotify/actions'
+import * as mopidyActions from '../services/mopidy/actions'
class Album extends React.Component{
@@ -24,12 +25,30 @@ class Album extends React.Component{
}
}
+ playTracks( tracks ){
+ var uris = [];
+ for( var i = 0; i < tracks.length; i++ ){
+ uris.push( tracks[i].uri )
+ }
+ this.props.mopidyActions.playTracks( uris )
+ }
+
+ playTrack( track ){
+ var uris = [track.uri];
+ this.props.mopidyActions.playTracks( uris )
+ }
+
render(){
if( this.props.spotify.album ){
return (
{ this.props.spotify.album.name }
-
+ this.playTracks( tracks ) }
+ playTrack={ track => this.playTrack( track ) }
+ />
);
}
@@ -50,6 +69,7 @@ const mapStateToProps = (state, ownProps) => {
const mapDispatchToProps = (dispatch) => {
return {
+ mopidyActions: bindActionCreators(mopidyActions, dispatch),
spotifyActions: bindActionCreators(spotifyActions, dispatch)
}
}
diff --git a/src/js/views/Queue.js b/src/js/views/Queue.js
index 35e496dc..52ab375e 100755
--- a/src/js/views/Queue.js
+++ b/src/js/views/Queue.js
@@ -33,12 +33,29 @@ class Queue extends React.Component{
renderTrackList(){
if( this.props.mopidy && this.props.mopidy.tracks ){
return (
-
+ this.removeTracks( tracks ) }
+ playTracks={ null }
+ playTrack={ track => this.playTrack( track ) }
+ />
);
}
return null;
}
+ removeTracks( tracks ){
+ var tlids = [];
+ for( var i = 0; i < tracks.length; i++ ){
+ tlids.push( tracks[i].tlid )
+ }
+ this.props.actions.removeTracks( tlids )
+ }
+
+ playTrack( track ){
+ this.props.actions.changeTrack( track.tlid )
+ }
+
render(){
return (