From ea85f2b18d8e7b3ac0d0c70997e029cdedc7f541 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Tue, 16 May 2017 08:54:45 +1200 Subject: [PATCH] Pulling artist and albums from recommendations to build nicer info --- src/js/services/spotify/actions.js | 43 +++++++++++++++-- src/js/services/spotify/reducer.js | 6 ++- src/js/views/discover/Discover.js | 77 +++++++++++++++++++++++++++--- src/scss/views/_discover.scss | 8 ++++ 4 files changed, 123 insertions(+), 11 deletions(-) diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js index 6c1685b0..58151eb4 100755 --- a/src/js/services/spotify/actions.js +++ b/src/js/services/spotify/actions.js @@ -656,7 +656,7 @@ export function getFavorites(limit = 50, term = 'long_term'){ * * @param uris = array of artist or track URIs or a genre string **/ -export function getRecommendations(uris = []){ +export function getRecommendations(uris = [], limit = 20){ return (dispatch, getState) => { dispatch({type: 'SPOTIFY_RECOMMENDATIONS_LOADED', tracks: []}) @@ -693,13 +693,50 @@ export function getRecommendations(uris = []){ var data = 'seed_artists='+artists_ids.join(',') data += '&seed_tracks='+tracks_ids.join(',') data += '&seed_genres='+genres.join(',') + data += '&limit='+limit sendRequest(dispatch, getState, 'recommendations', 'GET', data) .then( response => { + + // We only get simple artist objects, so we need to + // get the full object. We'll add URIs to our recommendations + // anyway so we can proceed in the meantime + var artists_uris = [] + if (response.tracks.length > artists_ids.length && response.tracks.length > 10){ + while (artists_uris.length < 5){ + var random_index = Math.round(Math.random() * (response.tracks.length - 1)) + var artist = response.tracks[random_index].artists[0] + + // Make sure this artist is not already in our sample, and + // is not one of the seeds + if (!artists_uris.includes(artist.uri) && !artists_ids.includes(artist.id)){ + artists_uris.push(artist.uri) + dispatch(getArtist(artist.uri)) + } + } + } + + // Copy already loaded albums into array + var albums = [] + if (response.tracks.length > 10){ + for (var i = 0; i < 5; i++){ + var random_index = Math.round(Math.random() * (response.tracks.length - 1)) + albums.push(response.tracks[random_index].album) + } + } + + // Officially add albums to index + dispatch({ + type: 'ALBUMS_LOADED', + albums: albums + }) + dispatch({ type: 'SPOTIFY_RECOMMENDATIONS_LOADED', - tracks: response.tracks - }); + tracks: response.tracks, + artists_uris: artists_uris, + albums_uris: helpers.asURIs(albums) + }) }) } } diff --git a/src/js/services/spotify/reducer.js b/src/js/services/spotify/reducer.js index c1135253..0ad9dfb9 100755 --- a/src/js/services/spotify/reducer.js +++ b/src/js/services/spotify/reducer.js @@ -187,7 +187,11 @@ export default function reducer(spotify = {}, action){ {}, spotify, { - recommendations: action.tracks + recommendations: { + artists_uris: action.artists_uris, + albums_uris: action.albums_uris, + tracks: action.tracks + } }) case 'SPOTIFY_FAVORITES_LOADED': diff --git a/src/js/views/discover/Discover.js b/src/js/views/discover/Discover.js index 91c3480a..905eeac8 100755 --- a/src/js/views/discover/Discover.js +++ b/src/js/views/discover/Discover.js @@ -5,8 +5,9 @@ import { bindActionCreators } from 'redux' import FontAwesome from 'react-fontawesome' import SidebarToggleButton from '../../components/SidebarToggleButton' -import GridSlider from '../../components/GridSlider' import ArtistSentence from '../../components/ArtistSentence' +import ArtistGrid from '../../components/ArtistGrid' +import AlbumGrid from '../../components/AlbumGrid' import TrackList from '../../components/TrackList' import Parallax from '../../components/Parallax' import AddSeedField from '../../components/AddSeedField' @@ -29,7 +30,10 @@ class Discover extends React.Component{ } ], add_seed: '', - adding_seed: false + adding_seed: false, + artists: [], + albums: [], + tracks: [] } } @@ -42,7 +46,11 @@ class Discover extends React.Component{ } componentWillReceiveProps(newProps, newState){ - if (this.props.favorite_artists.length <= 0 && newProps.favorite_artists.length){ + + // When we've loaded favorite_artists. + // This indirectly listens for when the action has + // loaded new data. + if (this.props.favorite_artists.length <= 0 && newProps.favorite_artists.length > 0){ var initial_seeds = newProps.favorite_artists.sort(() => .5 - Math.random()) initial_seeds = initial_seeds.slice(0,2) @@ -52,8 +60,10 @@ class Discover extends React.Component{ } getRecommendations(seeds = this.state.seeds){ - var uris = helpers.asURIs(seeds) - this.props.spotifyActions.getRecommendations(uris) + if (seeds){ + var uris = helpers.asURIs(seeds) + this.props.spotifyActions.getRecommendations(uris, 50) + } } removeSeed(index){ @@ -93,6 +103,57 @@ class Discover extends React.Component{ ) } + renderResults(){ + if (helpers.isLoading(this.props.load_queue, 'spotify_recommendations')){ + return ( +
+
+
+ ) + } + + if (!this.props.recommendations || typeof(this.props.recommendations.albums_uris) === 'undefined' || typeof(this.props.recommendations.artists_uris) === 'undefined'){ + return null + } + + var albums = [] + if (this.props.recommendations.albums_uris && this.props.albums){ + for (var i = 0; i < this.props.recommendations.albums_uris.length; i++){ + var uri = this.props.recommendations.albums_uris[i] + if (this.props.albums.hasOwnProperty(uri)){ + albums.push(this.props.albums[uri]) + } + } + } + + var artists = [] + if (this.props.recommendations.artists_uris && this.props.artists){ + for (var i = 0; i < this.props.recommendations.artists_uris.length; i++){ + var uri = this.props.recommendations.artists_uris[i] + if (this.props.artists.hasOwnProperty(uri)){ + artists.push(this.props.artists[uri]) + } + } + } + + return ( +
+
+

Artists

+ +
+
+

Albums

+ +
+
+

Tracks

+ {this.props.recommendations.tracks ? : null} +
+
+ ) + } + render(){ return (
@@ -108,7 +169,7 @@ class Discover extends React.Component{ {this.renderSeeds()}
- {helpers.isLoading(this.props.load_queue, 'spotify_recommendations') ?
:
} + {this.renderResults()} ) } @@ -123,10 +184,12 @@ class Discover extends React.Component{ const mapStateToProps = (state, ownProps) => { return { + albums: state.ui.albums, + artists: state.ui.artists, authorized: state.spotify.authorized, load_queue: state.ui.load_queue, quick_search_results: (state.spotify.quick_search_results ? state.spotify.quick_search_results : {artists: [], tracks: []}), - recommendations: (state.spotify.recommendations ? state.spotify.recommendations : []), + recommendations: (state.spotify.recommendations ? state.spotify.recommendations : {}), favorite_artists: (state.spotify.favorite_artists ? state.spotify.favorite_artists : []), favorite_tracks: (state.spotify.favorite_tracks ? state.spotify.favorite_tracks : []) } diff --git a/src/scss/views/_discover.scss b/src/scss/views/_discover.scss index 622aec53..9dd5f06b 100755 --- a/src/scss/views/_discover.scss +++ b/src/scss/views/_discover.scss @@ -31,6 +31,14 @@ } } + section.grid-wrapper { + padding-bottom: 10px; + + &:not(:first-child){ + padding-top: 0; + } + } + .seeds { .seed {