diff --git a/src/js/helpers.js b/src/js/helpers.js index 8ba2b1d0..02203cda 100755 --- a/src/js/helpers.js +++ b/src/js/helpers.js @@ -455,11 +455,19 @@ export let setWindowTitle = function (track = false, play_state = false){ * @param key = string (the string to lookup) * @return boolean **/ -export let isLoading = function(load_queue = [], key = ''){ +export let isLoading = function(load_queue = [], keys = []){ + + // Loop all of our load queue items for (var load_queue_key in load_queue) { + + // Make sure it's not a root object method if (load_queue.hasOwnProperty(load_queue_key)){ - if (load_queue[load_queue_key] == key){ - return true + + // Loop all the keys we're looking for + for (var i = 0; i < keys.length; i++){ + if (load_queue[load_queue_key].startsWith(keys[i])){ + return true + } } } } diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js index 50563d16..84bff415 100755 --- a/src/js/services/spotify/actions.js +++ b/src/js/services/spotify/actions.js @@ -53,10 +53,17 @@ const sendRequest = ( dispatch, getState, endpoint, method = 'GET', data = false }, (xhr, status, error) => { dispatch(uiActions.stopLoading(loader_key)) + + // TODO: Catch 403 token_expired and force renewal + // Android Chrome mini-app doesn't seem to check date properly + // alert(error) + // Get the error message, jsson decode if necessary var message = xhr.responseText var response = JSON.parse(xhr.responseText) - if (response.error && response.error.message) message = response.error.message + if (response.error && response.error.message){ + message = response.error.message + } dispatch(uiActions.createNotification('Spotify: '+message,'bad')) console.error( endpoint+' failed', response) @@ -78,15 +85,17 @@ function getToken( dispatch, getState ){ return new Promise( (resolve, reject) => { // token is okay for now, so just resolve with the current token - if( getState().spotify.token_expiry && new Date().getTime() < getState().spotify.token_expiry ){ + if (getState().spotify.token_expiry && new Date().getTime() < getState().spotify.token_expiry){ resolve(getState().spotify.access_token) return } // token is expiring/expired, so go get a new one and resolve that - refreshToken( dispatch, getState ) + refreshToken(dispatch, getState) .then( - response => resolve(response.access_token), + response => { + resolve(response.access_token) + }, error => { dispatch({ type: 'SPOTIFY_DISCONNECTED' }) reject(error) @@ -98,7 +107,7 @@ function getToken( dispatch, getState ){ function refreshToken( dispatch, getState ){ return new Promise( (resolve, reject) => { - if( getState().spotify.authorized ){ + if (getState().spotify.authorized){ $.ajax({ method: 'GET', @@ -690,12 +699,13 @@ export function getRecommendations(uris = [], limit = 20){ } // construct our endpoint URL with all the appropriate arguments - var data = 'seed_artists='+artists_ids.join(',') - data += '&seed_tracks='+tracks_ids.join(',') - data += '&seed_genres='+genres.join(',') - data += '&limit='+limit + var endpoint = 'recommendations' + endpoint += '?seed_artists='+artists_ids.join(',') + endpoint += '&seed_tracks='+tracks_ids.join(',') + endpoint += '&seed_genres='+genres.join(',') + endpoint += '&limit='+limit - sendRequest(dispatch, getState, 'recommendations', 'GET', data) + sendRequest(dispatch, getState, endpoint) .then( response => { // We only get simple artist objects, so we need to diff --git a/src/js/views/Album.js b/src/js/views/Album.js index 5e5cba28..7c3b48e1 100755 --- a/src/js/views/Album.js +++ b/src/js/views/Album.js @@ -96,81 +96,66 @@ class Album extends React.Component{ } render(){ - if (this.props.album){ - var artists = [] - if (this.props.album.artists_uris && this.props.artists){ - for (var i = 0; i < this.props.album.artists_uris.length; i++){ - var uri = this.props.album.artists_uris[i] - if (this.props.artists.hasOwnProperty(uri)){ - artists.push(this.props.artists[uri]) - } + if (helpers.isLoading(this.props.load_queue,['spotify_albums/'+helpers.getFromUri('albumid',this.props.params.uri)])){ + return ( +
+
+
+ ) + } + + if (!this.props.album){ + return null + } + + var artists = [] + if (this.props.album.artists_uris && this.props.artists){ + for (var i = 0; i < this.props.album.artists_uris.length; i++){ + var uri = this.props.album.artists_uris[i] + if (this.props.artists.hasOwnProperty(uri)){ + artists.push(this.props.artists[uri]) } } - - return ( -
- - - - -
-
-   - {helpers.uriSource( this.props.params.uri )}  - {this.props.album.album_type ? this.props.album.album_type : 'album'} -
- -

{ this.props.album.name }

- -
    - { artists.length > 0 ?
  • : null } - { this.props.album.release_date ?
  • : null } -
  • - { this.props.album.tracks_total ? this.props.album.tracks_total : '0' } tracks,  - { this.props.album.tracks ? : '0 mins' } -
  • -
-
- -
- - { helpers.uriSource(this.props.params.uri) == 'spotify' ? : null } - this.handleContextMenu(e)} /> -
- -
- { this.props.album.tracks ? : null } - this.loadMore() }/> -
- -
- ); - - } else { - return ( -
- - -
-
- Album -
-

- -

-
    -
  • - -
  • -
-
-
- -
-
- ); - } + + return ( +
+ + + + +
+
+   + {helpers.uriSource( this.props.params.uri )}  + {this.props.album.album_type ? this.props.album.album_type : 'album'} +
+ +

{ this.props.album.name }

+ +
    + { artists.length > 0 ?
  • : null } + { this.props.album.release_date ?
  • : null } +
  • + { this.props.album.tracks_total ? this.props.album.tracks_total : '0' } tracks,  + { this.props.album.tracks ? : '0 mins' } +
  • +
+
+ +
+ + { helpers.uriSource(this.props.params.uri) == 'spotify' ? : null } + this.handleContextMenu(e)} /> +
+ +
+ { this.props.album.tracks ? : null } + this.loadMore() }/> +
+ +
+ ) } } @@ -183,6 +168,7 @@ class Album extends React.Component{ const mapStateToProps = (state, ownProps) => { return { + load_queue: state.ui.load_queue, artists: state.ui.artists, album: (state.ui.albums && typeof(state.ui.albums[ownProps.params.uri]) !== 'undefined' ? state.ui.albums[ownProps.params.uri] : false ), albums: state.ui.albums, diff --git a/src/js/views/Artist.js b/src/js/views/Artist.js index 85fbb6bd..9ce5f48b 100755 --- a/src/js/views/Artist.js +++ b/src/js/views/Artist.js @@ -96,6 +96,14 @@ class Artist extends React.Component{ } renderBody(){ + if (helpers.isLoading(this.props.load_queue,['spotify_artists/'+helpers.getFromUri('artistid',this.props.params.uri), 'lastfm_method=artist.getInfo'])){ + return ( +
+
+
+ ) + } + var scheme = helpers.uriSource( this.props.params.uri ); var related_artists = [] @@ -179,7 +187,8 @@ class Artist extends React.Component{ } render(){ - var scheme = helpers.uriSource( this.props.params.uri ); + + var scheme = helpers.uriSource( this.props.params.uri ) if ( this.props.artist && this.props.artist.images ){ var image = helpers.sizedImages( this.props.artist.images ).huge @@ -211,9 +220,7 @@ class Artist extends React.Component{ { this.renderSubViewMenu() } - - {this.props.artist ? this.renderBody() : null} - + {this.renderBody()} ); @@ -235,6 +242,7 @@ class Artist extends React.Component{ { this.renderSubViewMenu() } + {this.renderBody()} ); } @@ -250,6 +258,7 @@ class Artist extends React.Component{ const mapStateToProps = (state, ownProps) => { return { + load_queue: state.ui.load_queue, artist: (state.ui.artists && typeof(state.ui.artists[ownProps.params.uri]) !== 'undefined' ? state.ui.artists[ownProps.params.uri] : false ), artists: (state.ui.artists ? state.ui.artists : []), library_artists: (state.ui.library_artists ? state.ui.library_artists : []), diff --git a/src/js/views/Debug.js b/src/js/views/Debug.js index 816927c6..350fb4ce 100755 --- a/src/js/views/Debug.js +++ b/src/js/views/Debug.js @@ -77,7 +77,7 @@ class Debug extends React.Component{