From 4c6458aafcc921ffe650d64afbe557de4606ca62 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Mon, 13 Nov 2017 21:19:02 +1300 Subject: [PATCH] LastFM love/unlove track update; Link to privacy policy in settings #229 --- src/js/components/ContextMenu.js | 14 +- src/js/components/ProgressSlider.js | 2 +- src/js/services/core/middleware.js | 1 - src/js/services/lastfm/actions.js | 256 +++++++++++++++++----------- src/js/views/Settings.js | 2 +- src/js/views/Track.js | 8 +- 6 files changed, 174 insertions(+), 109 deletions(-) diff --git a/src/js/components/ContextMenu.js b/src/js/components/ContextMenu.js index 8dbd58dd..f692a1d6 100755 --- a/src/js/components/ContextMenu.js +++ b/src/js/components/ContextMenu.js @@ -57,9 +57,8 @@ class ContextMenu extends React.Component{ // if we're able to be in the LastFM library, run a check if (nextProps.lastfm_authorized && context.is_track && context.items_count == 1){ - if (nextProps.menu.items[0].uri && this.props.tracks[nextProps.menu.items[0].uri] !== undefined){ - var track = this.props.tracks[nextProps.menu.items[0].uri]; - this.props.lastfmActions.getTrack(track); + if (nextProps.menu.items[0].uri && this.props.tracks[nextProps.menu.items[0].uri] !== undefined && this.props.tracks[nextProps.menu.items[0].uri].userloved === undefined){ + this.props.lastfmActions.getTrack(nextProps.menu.items[0].uri); } } @@ -222,9 +221,9 @@ class ContextMenu extends React.Component{ toggleLoved(e, is_loved){ this.props.uiActions.hideContextMenu() if (is_loved){ - this.props.lastfmActions.unloveTrack(this.props.menu.items[0]) + this.props.lastfmActions.unloveTrack(this.props.menu.items[0].uri) } else { - this.props.lastfmActions.loveTrack(this.props.menu.items[0]) + this.props.lastfmActions.loveTrack(this.props.menu.items[0].uri) } } @@ -488,8 +487,9 @@ class ContextMenu extends React.Component{ ) - - if (helpers.isLoading(this.props.load_queue,['lastfm_track.getInfo'])){ + if (!this.props.lastfm_authorized){ + var toggle_loved = null; + } else if (helpers.isLoading(this.props.load_queue,['lastfm_track.getInfo'])){ var toggle_loved = ( diff --git a/src/js/components/ProgressSlider.js b/src/js/components/ProgressSlider.js index 009a4a9e..1e793ff3 100755 --- a/src/js/components/ProgressSlider.js +++ b/src/js/components/ProgressSlider.js @@ -54,7 +54,7 @@ class ProgressSlider extends React.Component{ const mapStateToProps = (state, ownProps) => { return { - current_track: (state.core.current_track !== undefined && state.core.tracks !== undefined && state.core.tracks[state.core.current_track] !== undefined ? state.core.tracks[state.core.current_track] : null), + current_track: (state.core.tracks[state.core.current_track_uri] !== undefined ? state.core.tracks[state.core.current_track_uri] : null), connected: state.mopidy.connected, time_position: state.mopidy.time_position, play_state: state.mopidy.play_state diff --git a/src/js/services/core/middleware.js b/src/js/services/core/middleware.js index c9826205..02364dca 100755 --- a/src/js/services/core/middleware.js +++ b/src/js/services/core/middleware.js @@ -570,7 +570,6 @@ const CoreMiddleware = (function(){ **/ case 'LOADED_MORE': - console.log(action); var parent_type_plural = action.parent_type+'s'; var parent_index = Object.assign({}, core[action.parent_type+'s']); var parent = Object.assign({}, parent_index[action.parent_key]); diff --git a/src/js/services/lastfm/actions.js b/src/js/services/lastfm/actions.js index 9a7ba9c1..8217a8c7 100755 --- a/src/js/services/lastfm/actions.js +++ b/src/js/services/lastfm/actions.js @@ -151,77 +151,6 @@ export function revokeAuthorization(){ } -/** - * Signed requests - **/ - -export function loveTrack(uri, artist, track){ - return (dispatch, getState) => { - artist = encodeURIComponent(artist); - var params = 'method=track.love&track='+track+'&artist='+artist; - sendSignedRequest(dispatch, getState, params) - .then( - response => { - dispatch({ - type: 'TRACK_LOADED', - track: { - uri: uri, - userloved: true - } - }); - } - ) - } -} - -export function unloveTrack(uri, artist, track){ - return (dispatch, getState) => { - artist = encodeURIComponent(artist); - var params = 'method=track.unlove&track='+track+'&artist='+artist; - sendSignedRequest(dispatch, getState, params) - .then( - response => { - dispatch({ - type: 'TRACK_LOADED', - track: { - uri: uri, - userloved: false - } - }); - } - ) - } -} - -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='+Math.floor(Date.now() / 1000); - - sendSignedRequest(dispatch, getState, params) - .then( - response => { - console.log("Scrobbled", response); - }, - error => { - dispatch(coreActions.handleException( - 'Could not scrobble track', - error, - (error.description ? error.description : null) - )); - } - ) - } -} - /** * Non-signed requests @@ -245,6 +174,55 @@ export function getMe(){ } } +export function getTrack(uri){ + return (dispatch, getState) => { + if (getState().core.tracks[uri] !== undefined){ + var track = getState().core.tracks[uri]; + if (!track.artists){ + dispatch(coreActions.handleException( + "Could not get track", + {}, + "Track has no artists" + )); + return; + } + } else { + dispatch(coreActions.handleException( + "Could not get track", + {}, + "Could not find track in index" + )); + return; + } + + var track_name = track.name; + var artist_name = encodeURIComponent(track.artists[0].name); + var params = 'method=track.getInfo&track='+track_name+'&artist='+artist_name; + if (getState().lastfm.session){ + params += '&username='+getState().lastfm.session.name; + } + sendRequest(dispatch, getState, params) + .then( + response => { + if (response.track){ + var merged_track = Object.assign( + {}, + { + uri: track.uri + }, + response.track, + track + ); + dispatch({ + type: 'TRACK_LOADED', + track: merged_track + }); + } + } + ) + } +} + export function getArtist(uri, artist, mbid = false){ return (dispatch, getState) => { if (mbid){ @@ -300,38 +278,122 @@ export function getAlbum(artist, album, mbid = false){ } } -export function getTrack(track, artist_name = null, track_name = null){ + + + +/** + * Signed requests + **/ + +export function loveTrack(uri){ return (dispatch, getState) => { - if (track){ - track_name = track.name; - if (track.artists){ - artist_name = track.artists[0].name; + if (getState().core.tracks[uri] !== undefined){ + var track = getState().core.tracks[uri]; + if (!track.artists){ + dispatch(coreActions.handleException( + "Could not love track", + track, + "Track has no artists" + )); + return; } + } else { + dispatch(coreActions.handleException( + "Could not love track", + track, + "Could not find track in index" + )); + return; } - artist_name = encodeURIComponent(artist_name); - var params = 'method=track.getInfo&track='+track_name+'&artist='+artist_name; - if (getState().lastfm.session){ - params += '&username='+getState().lastfm.session.name; - } - sendRequest(dispatch, getState, params) + + var artist = encodeURIComponent(track.artists[0].name); + var params = 'method=track.love&track='+track.name+'&artist='+artist; + sendSignedRequest(dispatch, getState, params) .then( response => { - if (response.track){ - var merged_track = Object.assign( - {}, - { - uri: track.uri - }, - response.track, - track - ); - dispatch({ - type: 'TRACK_LOADED', - track: merged_track - }); - } + track = Object.assign( + {}, + track, + { + userloved: true + } + ); + dispatch({ + type: 'TRACKS_LOADED', + tracks: [track] + }); } - ) + ); } } +export function unloveTrack(uri){ + return (dispatch, getState) => { + if (getState().core.tracks[uri] !== undefined){ + var track = getState().core.tracks[uri]; + if (!track.artists){ + dispatch(coreActions.handleException( + "Could not unlove track", + track, + "Track has no artists" + )); + return; + } + } else { + dispatch(coreActions.handleException( + "Could not unlove track", + track, + "Could not find track in index" + )); + return; + } + + var artist = encodeURIComponent(track.artists[0].name); + var params = 'method=track.unlove&track='+track.name+'&artist='+artist; + sendSignedRequest(dispatch, getState, params) + .then( + response => { + track = Object.assign( + {}, + track, + { + userloved: false + } + ); + dispatch({ + type: 'TRACKS_LOADED', + tracks: [track] + }); + } + ); + } +} + +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='+Math.floor(Date.now() / 1000); + + sendSignedRequest(dispatch, getState, params) + .then( + response => { + console.log("Scrobbled", response); + }, + error => { + dispatch(coreActions.handleException( + 'Could not scrobble track', + error, + (error.description ? error.description : null) + )); + } + ) + } +} \ No newline at end of file diff --git a/src/js/views/Settings.js b/src/js/views/Settings.js index 19bc02fa..f12c9a34 100755 --- a/src/js/views/Settings.js +++ b/src/js/views/Settings.js @@ -439,7 +439,7 @@ class Settings extends React.Component { Iris is an open-source project by James Barnsley. It is provided free and with absolutely no warranty. If you paid someone for this software, please let me know.

- Google Analytics is used to help trace issues and provide valuable insight into how we can continue to make improvements. + Google Analytics is used to help trace issues and provide valuable insight into how we can continue to make improvements. This may include personal information (eg Spotify Username). For more information, see terms and conditions.


diff --git a/src/js/views/Track.js b/src/js/views/Track.js index abe477dc..c714034c 100755 --- a/src/js/views/Track.js +++ b/src/js/views/Track.js @@ -57,7 +57,7 @@ class Track extends React.Component{ // Ready to load LastFM if (nextProps.lastfm_authorized){ - this.props.lastfmActions.getTrack(nextProps.track); + this.props.lastfmActions.getTrack(nextProps.track.uri); } // Ready to load lyrics @@ -77,6 +77,10 @@ class Track extends React.Component{ this.props.uiActions.showContextMenu(data) } + /** + * TODO: Identify why images being loaded breaks the thumbnail. Is there a new image array format + * we need to accommodate? + **/ loadTrack(props = this.props){ switch (helpers.uriSource(props.params.uri)){ @@ -105,7 +109,7 @@ class Track extends React.Component{ // Get the LastFM version of this track (provided we have artist info) if (props.lastfm_authorized){ - this.props.lastfmActions.getTrack(props.track); + this.props.lastfmActions.getTrack(props.track.uri); } // Ready for lyrics