diff --git a/src/js/components/Modal/EditPlaylistModal.js b/src/js/components/Modal/EditPlaylistModal.js index fe340bba..1555b01f 100755 --- a/src/js/components/Modal/EditPlaylistModal.js +++ b/src/js/components/Modal/EditPlaylistModal.js @@ -9,52 +9,86 @@ export default class EditPlaylistModal extends React.Component{ constructor(props){ super(props) this.state = { - submit_enabled: true, + error: null, name: this.props.data.name, + description: (this.props.data.description ? this.props.data.description : ''), is_public: this.props.data.is_public } } - setPlaylistName(name){ - var submit_enabled = false - if( name && name != '' ) submit_enabled = true - this.setState({ - name: name, - submit_enabled: submit_enabled - }) - } - savePlaylist(e){ e.preventDefault(); - this.props.uiActions.savePlaylist(this.props.data.uri, this.state.name, this.state.is_public) - this.props.uiActions.closeModal() - return false; + + if (!this.state.name || this.state.name == ''){ + this.setState({error: 'Name is required'}) + return false + } else { + this.props.uiActions.savePlaylist(this.props.data.uri, this.state.name, this.state.is_public, this.state.description) + this.props.uiActions.closeModal() + return false + } + } + + renderFields(){ + switch (helpers.uriSource(this.props.data.uri)){ + + case 'spotify': + return ( +
+
+ this.setState({ name: e.target.value })} + value={ this.state.name } /> +
+
+ this.setState({ description: e.target.value })} + value={ this.state.description } /> +
+
+ +
+
+ ) + break + + default: + return ( +
+
+ this.setState({ name: e.target.value })} + value={ this.state.name } /> +
+
+ ) + } } render(){ return (

Edit playlist

+ {this.state.error ?

{this.state.error}

: null}
this.savePlaylist(e)}> -
- this.setPlaylistName( e.target.value )} - value={ this.state.name } /> -
-
- -
+ + {this.renderFields()} +
- +
diff --git a/src/js/services/mopidy/middleware.js b/src/js/services/mopidy/middleware.js index 43c723a1..58a4e4cd 100755 --- a/src/js/services/mopidy/middleware.js +++ b/src/js/services/mopidy/middleware.js @@ -1,5 +1,6 @@ import Mopidy from 'mopidy' +import { hashHistory } from 'react-router' import * as helpers from '../../helpers' var mopidyActions = require('./actions.js') @@ -733,17 +734,33 @@ const MopidyMiddleware = (function(){ }); break - case 'MOPIDY_SAVE_PLAYLIST': + case 'MOPIDY_SAVE_PLAYLIST': + var uri = action.key + instruct( socket, store, 'playlists.lookup', { uri: action.key }) .then( response => { var playlist = Object.assign({}, response, { name: action.name }) instruct( socket, store, 'playlists.save', { playlist: playlist } ) .then( response => { + store.dispatch({ type: 'PLAYLIST_UPDATED', - key: action.key, + key: action.key, playlist: playlist }) + + // When we rename a playlist, the URI also changes to reflect the name change + // We need to update our index, as well as redirect our current page URL + if (action.key != response.key){ + store.dispatch({ + type: 'PLAYLIST_KEY_UPDATED', + key: action.key, + new_key: response.uri + }) + hashHistory.push(global.baseURL+'playlist/'+response.uri) + } + + store.dispatch(uiActions.createNotification('Saved')) }) }); break @@ -793,7 +810,8 @@ const MopidyMiddleware = (function(){ case 'MOPIDY_CREATE_PLAYLIST': instruct( socket, store, 'playlists.create', { name: action.name, uri_scheme: action.scheme }) - .then( response => { + .then( response => { + store.dispatch(uiActions.createNotification('Created playlist')) // re-load our global playlists //store.dispatch({ type: 'MOPIDY_GET_PLAYLISTS' }); @@ -803,6 +821,7 @@ const MopidyMiddleware = (function(){ case 'MOPIDY_DELETE_PLAYLIST': instruct( socket, store, 'playlists.delete', { uri: action.key }) .then( response => { + store.dispatch(uiActions.createNotification('Deleted playlist')) // re-load our global playlists // store.dispatch({ type: 'MOPIDY_PLAYLISTS' }); diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js index 01efb703..50fda403 100755 --- a/src/js/services/spotify/actions.js +++ b/src/js/services/spotify/actions.js @@ -1095,23 +1095,34 @@ export function createPlaylist( name, is_public ){ dispatch({ type: 'LIBRARY_PLAYLISTS_LOADED', uris: [response.uri] - }); + }) + + dispatch(uiActions.createNotification('Created playlist')) }) } } -export function savePlaylist(uri, name, is_public){ +export function savePlaylist(uri, name, is_public, description){ return (dispatch, getState) => { - sendRequest( dispatch, getState, 'users/'+ getState().spotify.me.id +'/playlists/'+ helpers.getFromUri('playlistid',uri), 'PUT', { name: name, public: is_public } ) + var data = { + name: name, + public: is_public, + description: description + } + + sendRequest( dispatch, getState, 'users/'+ getState().spotify.me.id +'/playlists/'+ helpers.getFromUri('playlistid',uri), 'PUT', data) .then( response => { dispatch({ type: 'PLAYLIST_UPDATED', + key: uri, playlist: { name: name, - public: is_public + public: is_public, + description: description } - }); + }) + dispatch(uiActions.createNotification('Saved')) }) } } diff --git a/src/js/services/spotify/middleware.js b/src/js/services/spotify/middleware.js index 79fe475d..f4d7f82b 100755 --- a/src/js/services/spotify/middleware.js +++ b/src/js/services/spotify/middleware.js @@ -72,7 +72,7 @@ const SpotifyMiddleware = (function(){ store.dispatch( uiActions.createNotification( "Must be logged in to Spotify to do that", 'bad' ) ) return } - store.dispatch( spotifyActions.savePlaylist( action.key, action.name, action.is_public )) + store.dispatch( spotifyActions.savePlaylist( action.key, action.name, action.is_public, action.description )) break // when radio returns diff --git a/src/js/services/ui/actions.js b/src/js/services/ui/actions.js index bcfb56c5..54f9af65 100755 --- a/src/js/services/ui/actions.js +++ b/src/js/services/ui/actions.js @@ -130,7 +130,7 @@ export function reorderPlaylistTracks( uri, indexes, insert_before, snapshot_id } } -export function savePlaylist( uri, name, is_public = false ){ +export function savePlaylist(uri, name, is_public = false, description = ''){ switch( helpers.uriSource( uri ) ){ case 'spotify': @@ -138,7 +138,8 @@ export function savePlaylist( uri, name, is_public = false ){ type: 'SPOTIFY_SAVE_PLAYLIST', key: uri, name: name, - is_public: is_public + is_public: is_public, + description: (description == '' ? null : description) } case 'm3u': diff --git a/src/js/services/ui/reducer.js b/src/js/services/ui/reducer.js index 8561181e..9012205e 100755 --- a/src/js/services/ui/reducer.js +++ b/src/js/services/ui/reducer.js @@ -471,7 +471,22 @@ export default function reducer(ui = {}, action){ } playlists[action.key] = merged_playlist - return Object.assign({}, ui, { playlists: playlists }); + return Object.assign({}, ui, { playlists: playlists }) + + case 'PLAYLIST_KEY_UPDATED': + var playlists = Object.assign([], ui.playlists) + + // URI not in our index? No change needed then + if (typeof(playlists[action.key]) === 'undefined'){ + return ui + } + + // Delete our old playlist by key, and add by new key + var playlist = Object.assign({}, playlists[action.key]) + delete playlists[action.key] + playlists[playlist.uri] = playlist + + return Object.assign({}, ui, { playlists: playlists }) case 'PLAYLISTS_LOADED': var playlists = Object.assign([], ui.playlists) diff --git a/src/js/views/Playlist.js b/src/js/views/Playlist.js index 0901020d..4d79ce2a 100755 --- a/src/js/views/Playlist.js +++ b/src/js/views/Playlist.js @@ -124,7 +124,7 @@ class Playlist extends React.Component{ return (
- + this.handleContextMenu(e)} />
) diff --git a/src/scss/components/_modal.scss b/src/scss/components/_modal.scss index 5ee9d488..e08351c3 100755 --- a/src/scss/components/_modal.scss +++ b/src/scss/components/_modal.scss @@ -43,13 +43,10 @@ padding-bottom: 20px; input[type="text"]{ - background: transparent; - font-size: 24px; - border-bottom: 2px solid #FFFFFF; - padding-left: 0; - padding-right: 0; + background: $dark_grey; + font-size: 18px; width: 100%; - color: #FFFFFF; + color: $white; &:focus, &:active {