diff --git a/src/js/components/LastfmLoveButton.js b/src/js/components/LastfmLoveButton.js index 7c59122f..3b47ada3 100755 --- a/src/js/components/LastfmLoveButton.js +++ b/src/js/components/LastfmLoveButton.js @@ -37,7 +37,7 @@ class FollowButton extends React.Component{ if (!this.props.lastfm_authorized){ return - } else if (this.props.loved === true){ + } else if (this.props.is_loved && this.props.is_loved !== "0"){ return } else { return diff --git a/src/js/services/lastfm/actions.js b/src/js/services/lastfm/actions.js index ec790ee8..d93329a8 100755 --- a/src/js/services/lastfm/actions.js +++ b/src/js/services/lastfm/actions.js @@ -33,21 +33,32 @@ const sendRequest = (dispatch, getState, params, signed = false) => { $.ajax(config).then( response => { - dispatch(uiActions.stopLoading(loader_key)) - resolve(response) + dispatch(uiActions.stopLoading(loader_key)); + if (response.error){ + reject({ + config: config, + error: response + }); + } else { + resolve(response); + } }, (xhr, status, error) => { - dispatch(uiActions.stopLoading(loader_key)) - dispatch(coreActions.handleException( - 'LastFM: '+xhr.responseText, - { - config: config, - error: error, - status: status, - xhr: xhr - } - )); - reject(error) + dispatch(uiActions.stopLoading(loader_key)); + + // Snatch a more meaningful error + var description = null; + if (xhr.responseJSON.message){ + description = xhr.responseJSON.message; + } + + reject({ + config: config, + error: error, + description: description, + status: status, + xhr: xhr + }); } ) }) @@ -64,8 +75,18 @@ const sendRequest = (dispatch, getState, params, signed = false) => { const sendSignedRequest = (dispatch, getState, params) => { return new Promise((resolve, reject) => { + // Not authorized + if (!getState().lastfm.session){ + reject({ + params: params, + error: "No active LastFM session" + }); + } + var loader_key = helpers.generateGuid() - dispatch(uiActions.startLoading(loader_key, 'lastfm_'+params)) + dispatch(uiActions.startLoading(loader_key, 'lastfm_'+params)); + + params += "&sk="+getState().lastfm.session.key; var config = { method: 'GET', @@ -75,33 +96,33 @@ const sendSignedRequest = (dispatch, getState, params) => { } $.ajax(config).then( - response => { - var signed_params = ""; - for (var key in response){ - if (response.hasOwnProperty(key)){ - if (signed_params != ""){ - signed_params += "&" - } - signed_params += key+'='+response[key]; + response => { + var signed_params = ""; + for (var key in response){ + if (response.hasOwnProperty(key)){ + if (signed_params != ""){ + signed_params += "&" } + signed_params += key+'='+response[key]; } - dispatch(uiActions.stopLoading(loader_key)) - return sendRequest(dispatch, getState, signed_params, true) - }, - (xhr, status, error) => { - dispatch(uiActions.stopLoading(loader_key)) - dispatch(coreActions.handleException( - 'LastFM: '+xhr.responseText, - { - config: config, - error: error, - status: status, - xhr: xhr - } - )); - reject(error) } - ); + + dispatch(uiActions.stopLoading(loader_key)) + sendRequest(dispatch, getState, signed_params, true) + .then( + response => { + resolve(response); + }, + error => { + reject(error); + } + ); + }, + (xhr, status, error) => { + dispatch(uiActions.stopLoading(loader_key)); + reject(error) + } + ); }) } @@ -164,7 +185,6 @@ export function loveTrack(uri, artist, track){ sendSignedRequest(dispatch, getState, params) .then( response => { - console.log(response); dispatch({ type: 'TRACK_LOADED', key: uri, @@ -277,11 +297,13 @@ export function getAlbum(artist, album, mbid = false){ export function getTrack(track, artist_name = null, track_name = null){ return (dispatch, getState) => { if (track){ - artist_name = track.artist[0].name; track_name = track.name; + if (track.artists){ + artist_name = track.artists[0].name; + } } artist_name = encodeURIComponent(artist_name); - var params = 'method=track.getInfo&track='+track+'&artist='+artist; + var params = 'method=track.getInfo&track='+track_name+'&artist='+artist_name; if (getState().lastfm.session){ params += '&username='+getState().lastfm.session.name; } @@ -296,7 +318,7 @@ export function getTrack(track, artist_name = null, track_name = null){ ); dispatch({ type: 'TRACK_LOADED', - key: uri, + key: merged_track.uri, track: merged_track }); } @@ -305,3 +327,32 @@ export function getTrack(track, artist_name = null, track_name = null){ } } +export function scrobble(track){ + return (dispatch, getState) => { + var track_name = track.name; + var artist_name = "Unknown"; + if (track.artists){ + artist_name = track.artists[0].name; + } + var artist_name = encodeURIComponent(artist_name); + + var params = 'method=track.scrobble'; + params += '&track='+track_name+'&artist='+artist_name; + params += '×tamp='+Date.now(); + + sendSignedRequest(dispatch, getState, params) + .then( + response => { + console.log("Scrobbled", response); + }, + error => { + dispatch(coreActions.handleException( + 'Could not scrobble track', + error, + (error.description ? error.description : null) + )); + } + ) + } +} + diff --git a/src/js/services/lastfm/middleware.js b/src/js/services/lastfm/middleware.js index 6759089b..6f0a7e6a 100755 --- a/src/js/services/lastfm/middleware.js +++ b/src/js/services/lastfm/middleware.js @@ -32,6 +32,16 @@ const LastfmMiddleware = (function(){ next(action); break; + case 'MOPIDY_CURRENTTLTRACK': + if (action.data && action.data.track){ + if (state.lastfm.session){ + store.dispatch(lastfmActions.scrobble(action.data.track)); + } + } + next(action); + break; + + // This action is irrelevant to us, pass it on to the next middleware default: return next(action); diff --git a/src/js/services/localstorage/middleware.js b/src/js/services/localstorage/middleware.js index 365d2b8a..6149da5b 100755 --- a/src/js/services/localstorage/middleware.js +++ b/src/js/services/localstorage/middleware.js @@ -178,6 +178,17 @@ const localstorageMiddleware = (function(){ ); localStorage.setItem('lastfm', JSON.stringify(lastfm)); break; + + case 'LASTFM_AUTHORIZATION_REVOKED': + var lastfm = JSON.parse(localStorage.getItem('lastfm') ); + lastfm = Object.assign( + {}, + { + session: null + } + ); + localStorage.setItem('lastfm', JSON.stringify(lastfm)); + break; } } diff --git a/src/js/views/Track.js b/src/js/views/Track.js index 3213325e..abe477dc 100755 --- a/src/js/views/Track.js +++ b/src/js/views/Track.js @@ -52,9 +52,18 @@ class Track extends React.Component{ } } - // We don't have lyrics, and we have just received our artists - if (!nextProps.track.lyrics_results && !this.props.track.artists && nextProps.track.artists){ - this.props.geniusActions.findTrackLyrics(nextProps.track); + // We have just received our full track info (with artists) + if (!this.props.track.artists && nextProps.track.artists){ + + // Ready to load LastFM + if (nextProps.lastfm_authorized){ + this.props.lastfmActions.getTrack(nextProps.track); + } + + // Ready to load lyrics + if (!nextProps.track.lyrics_results){ + this.props.geniusActions.findTrackLyrics(nextProps.track); + } } } @@ -91,14 +100,18 @@ class Track extends React.Component{ break; } - // Get the LastFM version of this track - if (props.lastfm_authorized){ - //this.props.lastfmActions.getTrack(this.props.track); - } + // We have artist info already + if (props.track && props.track.artists){ - // We don't have lyrics, but the track (and artists) is already loaded - if (props.track && !props.track.lyrics_results && props.track.artists){ - this.props.geniusActions.findTrackLyrics(props.track); + // Get the LastFM version of this track (provided we have artist info) + if (props.lastfm_authorized){ + this.props.lastfmActions.getTrack(props.track); + } + + // Ready for lyrics + if (props.track && !props.track.lyrics_results){ + this.props.geniusActions.findTrackLyrics(props.track); + } } } @@ -218,7 +231,7 @@ class Track extends React.Component{
- + this.handleContextMenu(e)} />
@@ -248,7 +261,7 @@ const mapStateToProps = (state, ownProps) => { albums: state.core.albums, spotify_library_albums: state.spotify.library_albums, local_library_albums: state.mopidy.library_albums, - lastfm_authorized: state.spotify.session, + lastfm_authorized: state.lastfm.session, spotify_authorized: state.spotify.authorization, mopidy_connected: state.mopidy.connected };