diff --git a/src/js/Index/Index.js b/src/js/Index/Index.js index 4613e4e..9de99a9 100644 --- a/src/js/Index/Index.js +++ b/src/js/Index/Index.js @@ -9,7 +9,39 @@ class Index extends Component{ } render(){ - return

welcome to playlist manager!

; + return ( + + + + + + + + + + + + + + + + + + + + +
+

playlist manager

+
+ construct playlists from selections of other playlists +
+ group sub-genre playlists +
+ optionally append recommendations generated by spotify +
+

playlists are run multiple times a day +
+ ); } } diff --git a/src/js/Playlist/NewPlaylist.js b/src/js/Playlist/NewPlaylist.js index 9e8cc19..bb00e7a 100644 --- a/src/js/Playlist/NewPlaylist.js +++ b/src/js/Playlist/NewPlaylist.js @@ -10,53 +10,83 @@ class NewPlaylist extends Component { super(props); this.state = { name: '', - type: 'normal' + type: 'default', + description: '' } this.handleInputChange = this.handleInputChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } + componentDidMount(){ + this.setDescription('default'); + } + + setDescription(value){ + switch(value){ + case 'default': + this.setState({ + description: 'merge playlists as-is with deduplication by spotify id' + }) + break; + case 'recents': + this.setState({ + description: "select songs from playlists which have been added since a variable number of days" + }) + break; + } + } + handleInputChange(event){ this.setState({ [event.target.name]: event.target.value }); + this.setDescription(event.target.value); } handleSubmit(event){ - axios.get('/api/playlists') - .then((response) => { - - var names = response.data.playlists.map(entry => entry.name) - - var sameName = names.includes(this.state.name); - if(sameName == false){ - axios.put('/api/playlist', { - name: this.state.name, - parts: [], - playlist_references: [], - shuffle: false, - type: this.state.type, - }).then((response) => { - showMessage(`${this.state.name} created`); - }).catch((error) => { - showMessage(`error creating playlist (${error.response.status})`); - }); - }else{ - showMessage('named playlist already exists'); - } - }) - .catch((error) => { - showMessage(`error getting playlists (${error.response.status})`); + var name = this.state.name; + this.setState({ + name: '' }); + + if(name.length != 0){ + axios.get('/api/playlists') + .then((response) => { + + var names = response.data.playlists.map(entry => entry.name) + + var sameName = names.includes(this.state.name); + if(sameName == false){ + axios.put('/api/playlist', { + name: name, + parts: [], + playlist_references: [], + shuffle: false, + type: this.state.type, + }).then((response) => { + showMessage(`${this.state.name} created`); + }).catch((error) => { + showMessage(`error creating playlist (${error.response.status})`); + }); + }else{ + showMessage('named playlist already exists'); + } + }) + .catch((error) => { + showMessage(`error getting playlists (${error.response.status})`); + }); + }else{ + showMessage('enter name'); + } } render(){ return ( - +
@@ -64,7 +94,7 @@ class NewPlaylist extends Component { @@ -83,6 +113,11 @@ class NewPlaylist extends Component { + + +
-

new playlist

+

new playlist

+

{this.state.description} +
); diff --git a/src/js/Playlist/PlaylistView.js b/src/js/Playlist/PlaylistView.js index 71a0a0f..222d107 100644 --- a/src/js/Playlist/PlaylistView.js +++ b/src/js/Playlist/PlaylistView.js @@ -11,6 +11,7 @@ class PlaylistView extends Component{ name: this.props.match.params.name, parts: [], playlists: [], + filteredPlaylists: [], playlist_references: [], type: null, @@ -50,8 +51,13 @@ class PlaylistView extends Component{ return 0; }); + var filteredPlaylists = playlists.data.playlists.filter((entry) => entry.name != this.state.name); + this.setState(info.data); - this.setState({playlists: playlists.data.playlists}); + this.setState({ + playlists: playlists.data.playlists, + newPlaylistReference: filteredPlaylists.length > 0 ? filteredPlaylists[0].name : '' + }); })) .catch((error) => { showMessage(`error getting playlist info (${error.response.status})`); @@ -67,6 +73,7 @@ class PlaylistView extends Component{ } handleInputChange(event){ + this.setState({ [event.target.name]: event.target.value }); @@ -122,60 +129,75 @@ class PlaylistView extends Component{ } handleAddPart(event){ + + if(this.state.newPlaylistName.length != 0){ - var check = this.state.parts.filter((e) => { - return e == event.target.value; - }); + var check = this.state.parts.includes(this.state.newPlaylistName); - if(check.length == 0) { - var parts = this.state.parts.slice(); - parts.push(this.state.newPlaylistName); + if(check == false) { + var parts = this.state.parts.slice(); + parts.push(this.state.newPlaylistName); - parts.sort(function(a, b){ - if(a < b) { return -1; } - if(a > b) { return 1; } - return 0; - }); + parts.sort(function(a, b){ + if(a < b) { return -1; } + if(a > b) { return 1; } + return 0; + }); - this.setState({ - parts: parts, - newPlaylistName: '' - }); - axios.post('/api/playlist', { - name: this.state.name, - parts: parts - }).catch((error) => { - showMessage(`error adding part (${error.response.status})`); - }); + this.setState({ + parts: parts, + newPlaylistName: '' + }); + axios.post('/api/playlist', { + name: this.state.name, + parts: parts + }).catch((error) => { + showMessage(`error adding part (${error.response.status})`); + }); + }else{ + showMessage('playlist already added'); + } + + }else{ + showMessage('enter playlist name'); } } handleAddReference(event){ - - var check = this.state.playlist_references.filter((e) => { - return e == event.target.value; - }); - if(check.length == 0) { - var playlist_references = this.state.playlist_references.slice(); - playlist_references.push(this.state.newPlaylistReference); + if(this.state.newPlaylistReference.length != 0){ - playlist_references.sort(function(a, b){ - if(a < b) { return -1; } - if(a > b) { return 1; } - return 0; - }); - - this.setState({ - playlist_references: playlist_references, - newPlaylistReference: '' - }); - axios.post('/api/playlist', { - name: this.state.name, - playlist_references: playlist_references - }).catch((error) => { - showMessage(`error adding reference (${error.response.status})`); - }); + var check = this.state.playlist_references.includes(this.state.newPlaylistReference); + + if(check == false) { + var playlist_references = this.state.playlist_references.slice(); + playlist_references.push(this.state.newPlaylistReference); + + playlist_references.sort(function(a, b){ + if(a < b) { return -1; } + if(a > b) { return 1; } + return 0; + }); + + var filteredPlaylists = this.state.playlists.filter((entry) => entry.name != this.state.name); + + this.setState({ + playlist_references: playlist_references, + newPlaylistReference: filteredPlaylists.length > 0 ? filteredPlaylists[0].name : '' + }); + axios.post('/api/playlist', { + name: this.state.name, + playlist_references: playlist_references + }).catch((error) => { + showMessage(`error adding reference (${error.response.status})`); + }); + + }else{ + showMessage('playlist already added'); + } + + }else{ + showMessage('no other playlists to add'); } } @@ -218,11 +240,20 @@ class PlaylistView extends Component{ } handleRun(event){ - axios.get('/api/playlist/run', {params: {name: this.state.name}}) - .then((reponse) => { - showMessage(`${this.state.name} ran`); - }) - .catch((error) => { + axios.get('/api/user') + .then((response) => { + if(response.data.spotify_linked == true){ + axios.get('/api/playlist/run', {params: {name: this.state.name}}) + .then((reponse) => { + showMessage(`${this.state.name} ran`); + }) + .catch((error) => { + showMessage(`error running ${this.state.name} (${error.response.status})`); + }); + }else{ + showMessage(`link spotify before running`); + } + }).catch((error) => { showMessage(`error running ${this.state.name} (${error.response.status})`); }); } @@ -239,6 +270,11 @@ class PlaylistView extends Component{ { this.state.playlist_references.length > 0 && } { this.state.parts.length > 0 && } + + +

spotify playlist can be the name of either your own created playlist or one you follow, names are case sensitive + + + placeholder="spotify playlist name"> @@ -258,7 +294,9 @@ class PlaylistView extends Component{ className="full-width" value={this.state.newPlaylistReference} onChange={this.handleInputChange}> - { this.state.playlists.map((entry) => ) } + { this.state.playlists + .filter((entry) => entry.name != this.state.name) + .map((entry) => ) } @@ -287,7 +325,7 @@ class PlaylistView extends Component{ - recommendations sample size + number of recommendations { this.state.type == 'recents' && - + added since (days) @@ -309,7 +347,16 @@ class PlaylistView extends Component{ value={this.state.day_boundary} onChange={this.handleInputChange}> - + + } + { this.state.type == 'recents' && + + +

'recents' playlists search for and include this months and last months playlists when named in the format +

[month] [year] +

e.g july 19 (lowercase) + + } diff --git a/src/js/Playlist/PlaylistsView.js b/src/js/Playlist/PlaylistsView.js index 024340f..d0c3a09 100644 --- a/src/js/Playlist/PlaylistsView.js +++ b/src/js/Playlist/PlaylistsView.js @@ -41,12 +41,21 @@ class PlaylistsView extends Component { } handleRunPlaylist(name, event){ - axios.get('/api/playlist/run', {params: {name: name}}) + axios.get('/api/user') .then((response) => { - showMessage(`${name} ran`); - }) - .catch((error) => { - showMessage(`error running ${name} (${error.response.status})`); + if(response.data.spotify_linked == true){ + axios.get('/api/playlist/run', {params: {name: name}}) + .then((response) => { + showMessage(`${name} ran`); + }) + .catch((error) => { + showMessage(`error running ${name} (${error.response.status})`); + }); + }else{ + showMessage(`link spotify before running`); + } + }).catch((error) => { + showMessage(`error running ${this.state.name} (${error.response.status})`); }); } @@ -61,12 +70,21 @@ class PlaylistsView extends Component { } handleRunAll(event){ - axios.get('/api/playlist/run/user') + axios.get('/api/user') .then((response) => { - showMessage("all playlists ran"); - }) - .catch((error) => { - showMessage(`error running all (${error.response.status})`); + if(response.data.spotify_linked == true){ + axios.get('/api/playlist/run/user') + .then((response) => { + showMessage("all playlists ran"); + }) + .catch((error) => { + showMessage(`error running all (${error.response.status})`); + }); + }else{ + showMessage(`link spotify before running`); + } + }).catch((error) => { + showMessage(`error running ${this.state.name} (${error.response.status})`); }); } @@ -88,16 +106,25 @@ class PlaylistsView extends Component { function Table(props){ return ( + { props.playlists.length == 0 ? ( + + + + + + ) : ( { props.playlists.map((playlist) => ) } - { props.playlists.length > 0 && - } + + )}
+ no playlists +
); }