diff --git a/src/js/components/Modal.js b/src/js/components/Modal.js
index f2e20836..9ee2111d 100755
--- a/src/js/components/Modal.js
+++ b/src/js/components/Modal.js
@@ -12,6 +12,15 @@ import * as spotifyActions from '../services/spotify/actions'
class Modal extends React.Component{
+ constructor(props){
+ super(props)
+ this.state = {
+ playlist_name: '',
+ playlist_scheme: 'spotify',
+ playlist_private: true
+ }
+ }
+
playlistSelected( playlist_uri ){
this.props.uiActions.addTracksToPlaylist( playlist_uri, this.props.modal.data.track_indexes )
this.props.uiActions.closeModal()
@@ -49,6 +58,68 @@ class Modal extends React.Component{
)
}
+ createPlaylist(e){
+ e.preventDefault();
+ this.props.uiActions.createPlaylist( this.state.playlist_scheme, this.state.playlist_name, this.state.playlist_public );
+ return false;
+ }
+
+ renderCreatePlaylist(){
+ return (
+
+ )
+ }
+
render(){
if( !this.props.modal ) return null;
@@ -59,9 +130,8 @@ class Modal extends React.Component{
-
{ this.props.modal.name }
-
- { this.renderEditablePlaylists() }
+ { this.props.modal.name == 'add_to_playlist' ? this.renderEditablePlaylists() : null }
+ { this.props.modal.name == 'create_playlist' ? this.renderCreatePlaylist() : null }
diff --git a/src/js/components/Sidebar.js b/src/js/components/Sidebar.js
index d4836fc1..4eed86af 100755
--- a/src/js/components/Sidebar.js
+++ b/src/js/components/Sidebar.js
@@ -62,15 +62,15 @@ class Sidebar extends React.Component{
Playlists
-
+
Artists
-
+
Albums
-
+
Tracks
diff --git a/src/js/services/mopidy/actions.js b/src/js/services/mopidy/actions.js
index 60792281..5901c070 100755
--- a/src/js/services/mopidy/actions.js
+++ b/src/js/services/mopidy/actions.js
@@ -125,6 +125,13 @@ export function setTimePosition( time_position ){
* Asset-oriented actions
**/
+export function deletePlaylist( uri ){
+ return {
+ type: 'MOPIDY_DELETE_PLAYLIST',
+ uri: uri
+ }
+}
+
export function getPlaylists(){
return { type: 'MOPIDY_PLAYLISTS' }
}
diff --git a/src/js/services/mopidy/middleware.js b/src/js/services/mopidy/middleware.js
index 48b1e984..6f8fe1c0 100755
--- a/src/js/services/mopidy/middleware.js
+++ b/src/js/services/mopidy/middleware.js
@@ -85,18 +85,30 @@ const MopidyMiddleware = (function(){
var callParts = call.split('.');
var model = callParts[0];
var method = callParts[1];
- if( method ){
- var mopidyObject = ws[model][method]
- var property = method;
- }else{
- var mopidyObject = ws[model]
- var property = model;
- }
-
- property = property.replace('get','');
- property = property.replace('set','');
return new Promise( (resolve, reject) => {
+
+ if( model in ws ){
+ if( method in ws[model] ){
+ var mopidyObject = ws[model][method]
+ var property = method;
+ }else{
+ var mopidyObject = ws[model]
+ var property = model;
+ }
+ }else{
+ var error = {
+ message: 'Call to an invalid object. Check your are calling a valid Mopidy endpoint.',
+ call: call,
+ value: value
+ }
+ console.error(error)
+ reject(error)
+ }
+
+ property = property.replace('get','');
+ property = property.replace('set','');
+
mopidyObject( value )
.then(
response => {
@@ -219,32 +231,39 @@ const MopidyMiddleware = (function(){
uris.push( playlist.tracks[i].uri );
}
- instruct( socket, store, 'library.lookup', { uris: uris } )
- .then( response => {
+ // no tracks
+ if( uris.length <= 0 ){
+ store.dispatch({ type: 'MOPIDY_PLAYLIST_LOADED', data: playlist });
- for(var uri in response){
- if (response.hasOwnProperty(uri)) {
+ // tracks? let's flesh them out with full track objects, rather than just reference objects
+ }else{
+ instruct( socket, store, 'library.lookup', { uris: uris } )
+ .then( response => {
- var track = response[uri][0];
- if( track ){
-
- // find the track reference, and drop in the full track data
- function getByURI( trackReference ){
- return track.uri == trackReference.uri
- }
- var trackReferences = playlist.tracks.filter(getByURI);
-
- // there could be multiple instances of this track, so accommodate this
- for( var j = 0; j < trackReferences.length; j++){
- var key = playlist.tracks.indexOf( trackReferences[j] );
- playlist.tracks[ key ] = track;
+ for(var uri in response){
+ if (response.hasOwnProperty(uri)) {
+
+ var track = response[uri][0];
+ if( track ){
+
+ // find the track reference, and drop in the full track data
+ function getByURI( trackReference ){
+ return track.uri == trackReference.uri
+ }
+ var trackReferences = playlist.tracks.filter(getByURI);
+
+ // there could be multiple instances of this track, so accommodate this
+ for( var j = 0; j < trackReferences.length; j++){
+ var key = playlist.tracks.indexOf( trackReferences[j] );
+ playlist.tracks[ key ] = track;
+ }
}
}
}
- }
- store.dispatch({ type: 'MOPIDY_PLAYLIST_LOADED', data: playlist });
- })
+ store.dispatch({ type: 'MOPIDY_PLAYLIST_LOADED', data: playlist });
+ })
+ }
})
break;
@@ -292,6 +311,24 @@ 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_DELETE_PLAYLIST':
+ instruct( socket, store, 'playlists.delete', { uri: action.uri })
+ .then( response => {
+
+ // re-load our global playlists
+ store.dispatch({ type: 'MOPIDY_PLAYLISTS' });
+ });
+ break
+
case 'MOPIDY_ALBUM':
//store.dispatch({ type: 'MOPIDY_ALBUM_LOADED', data: false });
instruct( socket, store, 'library.lookup', action.data )
diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js
index 040f143e..615d7549 100755
--- a/src/js/services/spotify/actions.js
+++ b/src/js/services/spotify/actions.js
@@ -503,6 +503,16 @@ export function getSearchResults( query, type = 'album,artist,playlist,track', l
* Playlists
**/
+export function createPlaylist( name, is_private ){
+ return (dispatch, getState) => {
+
+ sendRequest( dispatch, getState, 'users/'+ getState().spotify.me.id +'/playlists/', 'POST', { name: name, public: !is_private } )
+ .then( response => {
+ dispatch( getAllLibraryPlaylists() );
+ })
+ }
+}
+
export function getPlaylist( uri ){
return (dispatch, getState) => {
diff --git a/src/js/services/spotify/middleware.js b/src/js/services/spotify/middleware.js
index 8d86ece7..6430c51b 100755
--- a/src/js/services/spotify/middleware.js
+++ b/src/js/services/spotify/middleware.js
@@ -16,6 +16,17 @@ const SpotifyMiddleware = (function(){
store.dispatch( actions.getMe() )
+ case 'SPOTIFY_CREATE_PLAYLIST':
+ var playlist = state.ui.playlist
+
+ if( !store.getState().spotify.authorized ){
+ alert('Must be logged in to Spotify to do this')
+ return
+ }
+ store.dispatch( actions.createPlaylist( action.name, action.is_private ))
+ break
+
+
case 'SPOTIFY_REMOVE_PLAYLIST_TRACKS':
var playlist = state.ui.playlist
diff --git a/src/js/services/ui/actions.js b/src/js/services/ui/actions.js
index 75b4df56..8f21b4e0 100755
--- a/src/js/services/ui/actions.js
+++ b/src/js/services/ui/actions.js
@@ -66,6 +66,26 @@ export function dragEnd(){
return { type: 'DRAG_END' }
}
+export function createPlaylist( scheme, name, is_private = false ){
+ switch( scheme ){
+
+ case 'spotify':
+ return {
+ type: 'SPOTIFY_CREATE_PLAYLIST',
+ name: name,
+ is_private: is_private
+ }
+
+ case 'm3u':
+ return {
+ type: 'MOPIDY_CREATE_PLAYLIST',
+ scheme: scheme,
+ name: name
+ }
+ }
+ return false
+}
+
export function removeTracksFromPlaylist( playlist_uri, tracks_indexes ){
switch( helpers.uriSource( playlist_uri ) ){
@@ -82,9 +102,6 @@ export function removeTracksFromPlaylist( playlist_uri, tracks_indexes ){
playlist_uri: playlist_uri,
tracks_indexes: tracks_indexes
}
-
- defaut:
- return ui
}
}
@@ -103,7 +120,6 @@ export function addTracksToPlaylist( playlist_uri, tracks ){
playlist_uri: playlist_uri,
tracks_uris: tracks_uris
}
- break;
case 'm3u':
return {
@@ -111,7 +127,6 @@ export function addTracksToPlaylist( playlist_uri, tracks ){
playlist_uri: playlist_uri,
tracks_uris: tracks_uris
}
- break;
}
}
diff --git a/src/js/views/Playlist.js b/src/js/views/Playlist.js
index 640e5386..9bf4c697 100755
--- a/src/js/views/Playlist.js
+++ b/src/js/views/Playlist.js
@@ -67,7 +67,7 @@ class Playlist extends React.Component{
}
delete(){
- alert('Delete me')
+ this.props.mopidyActions.deletePlaylist( this.props.params.uri )
}
removeTracks( track_indexes ){
@@ -75,15 +75,14 @@ class Playlist extends React.Component{
}
renderFollowOrDeleteButton(){
- if( !this.props.spotify_authorized ) return null
-
switch( helpers.uriSource( this.props.params.uri ) ){
case 'm3u':
return this.delete() } />
break
- case 'spotify':
+ case 'spotify':
+ if( !this.props.spotify_authorized ) return null
if( this.props.playlist.owner && this.props.playlist.owner.id == this.props.spotify_userid ){
return this.unfollow() } />
}else if( this.props.playlist.following ){
diff --git a/src/js/views/Settings.js b/src/js/views/Settings.js
index 669130ce..dce74d3d 100755
--- a/src/js/views/Settings.js
+++ b/src/js/views/Settings.js
@@ -93,43 +93,43 @@ class Settings extends React.Component{
Mopidy
Pusher
Spotify
Advanced
-