diff --git a/src/js/components/ArtistSentence.js b/src/js/components/ArtistSentence.js index f7e86273..74677d94 100755 --- a/src/js/components/ArtistSentence.js +++ b/src/js/components/ArtistSentence.js @@ -23,8 +23,9 @@ export default class ArtistSentence extends React.Component{ }else if( index < this.props.artists.length - 2 ){ separator = ', '; } - if( !artist.name ) artist.name = '-' - if( artist.uri ){ + if (!artist.name){ + var content = - + } else if (artist.uri){ var content = { artist.name } }else{ var content = { artist.name } diff --git a/src/js/components/FollowButton.js b/src/js/components/FollowButton.js index 42e62ce2..ecf4707d 100755 --- a/src/js/components/FollowButton.js +++ b/src/js/components/FollowButton.js @@ -30,23 +30,8 @@ class FollowButton extends React.Component{ render(){ if( !this.props.spotify_authorized || !this.props.uri ) return false - var item = {} - switch (helpers.uriType( this.props.uri )){ - case 'artist': - item = this.props.artists[this.props.uri] - break - case 'user': - item = this.props.users[this.props.uri] - break - case 'album': - item = this.props.albums[this.props.uri] - break - case 'playlist': - item = this.props.playlists[this.props.uri] - break - } - if( item.following === true ){ + if( this.props.is_following === true ){ return }else{ return @@ -56,11 +41,7 @@ class FollowButton extends React.Component{ const mapStateToProps = (state, ownProps) => { return { - spotify_authorized: state.spotify.authorized, - artists: state.ui.artists, - users: state.ui.users, - albums: state.ui.albums, - playlists: state.ui.playlists + spotify_authorized: state.spotify.authorized } } diff --git a/src/js/services/mopidy/middleware.js b/src/js/services/mopidy/middleware.js index 7a75229b..3bfb2777 100755 --- a/src/js/services/mopidy/middleware.js +++ b/src/js/services/mopidy/middleware.js @@ -313,7 +313,11 @@ const MopidyMiddleware = (function(){ } ) - store.dispatch({ type: 'PLAYLIST_LOADED', playlist: playlist }) + store.dispatch({ + type: 'PLAYLIST_LOADED', + uri: playlist.uri, + playlist: playlist + }) }) } }) @@ -336,7 +340,11 @@ const MopidyMiddleware = (function(){ // tracks? get the full track objects if( playlist.tracks.length > 0 ) store.dispatch({ type: 'MOPIDY_RESOLVE_PLAYLIST_TRACKS', tracks: playlist.tracks, uri: response.uri }) - store.dispatch({ type: 'PLAYLIST_LOADED', playlist: playlist }) + store.dispatch({ + type: 'PLAYLIST_LOADED', + uri: playlist.uri, + playlist: playlist + }) }) break; @@ -367,7 +375,11 @@ const MopidyMiddleware = (function(){ } } - store.dispatch({ type: 'PLAYLIST_TRACKS', tracks: tracks, uri: action.uri }) + store.dispatch({ + type: 'PLAYLIST_TRACKS', + tracks: tracks, + uri: action.uri + }) }) break @@ -425,7 +437,11 @@ const MopidyMiddleware = (function(){ var playlist = Object.assign({}, response, { name: action.name }) instruct( socket, store, 'playlists.save', { playlist: playlist } ) .then( response => { - store.dispatch({ type: 'PLAYLIST_UPDATED', uri: action.uri, playlist: playlist }) + store.dispatch({ + type: 'PLAYLIST_UPDATED', + uri: action.uri, + playlist: playlist + }) }) }); break diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js index 860f45f3..0d3c5134 100755 --- a/src/js/services/spotify/actions.js +++ b/src/js/services/spotify/actions.js @@ -355,14 +355,11 @@ export function getCategory( id ){ export function getNewReleases(){ return (dispatch, getState) => { - - dispatch({ type: 'SPOTIFY_NEW_RELEASES_LOADED', data: false }); - sendRequest( dispatch, getState, 'browse/new-releases?country='+getState().spotify.country+'&limit=50' ) .then( response => { dispatch({ type: 'SPOTIFY_NEW_RELEASES_LOADED', - data: response.albums + data: response }); }); } @@ -405,8 +402,6 @@ export function getSearchResults( query, type = 'album,artist,playlist,track', l export function following(uri, method = 'GET'){ return (dispatch, getState) => { - dispatch({ type: 'FOLLOWING_LOADING' }); - if( method == 'PUT' ) var is_following = true if( method == 'DELETE' ) var is_following = false @@ -450,7 +445,8 @@ export function following(uri, method = 'GET'){ if( response ) is_following = response if( typeof(is_following) === 'object' ) is_following = is_following[0] dispatch({ - type: asset_name.toUpperCase()+'_FOLLOWING_LOADED', + type: 'SPOTIFY_'+asset_name.toUpperCase()+'_FOLLOWING_LOADED', + uri: uri, is_following: is_following }); }); @@ -603,31 +599,29 @@ export function getArtist( uri ){ sendRequest( dispatch, getState, 'artists/'+ helpers.getFromUri('artistid', uri) +'/related-artists' ) .then( response => { - for (var i = 0; i < response.artists.length; i++){ - dispatch({ - type: 'ARTIST_LOADED', - artist: response.artists[i] - }); - } - Object.assign(artist, { related_artists: helpers.asURIs(response.artists) }); - }), - - sendRequest( dispatch, getState, 'artists/'+ helpers.getFromUri('artistid', uri) +'/albums' ) - .then( response => { - for (var i = 0; i < response.items.length; i++){ - dispatch({ - type: 'ALBUM_LOADED', - album: response.items[i] - }); - } - Object.assign(artist, { albums: helpers.asURIs(response.items), albums_more: response.next }); + dispatch({ + type: 'ARTISTS_LOADED', + artists: response.artists + }); + Object.assign(artist, { related_artists_uris: helpers.asURIs(response.artists) }); }) ).then( () => { dispatch({ type: 'ARTIST_LOADED', + uri: artist.uri, artist: artist }); + + // now go get our artist albums + sendRequest( dispatch, getState, 'artists/'+ helpers.getFromUri('artistid', uri) +'/albums' ) + .then( response => { + dispatch({ + type: 'SPOTIFY_ARTIST_ALBUMS_LOADED', + data: response, + uri: uri + }); + }) }); } } @@ -732,19 +726,34 @@ export function getAlbum( uri ){ sendRequest( dispatch, getState, 'albums/'+ helpers.getFromUri('albumid', uri) ) .then( response => { + // dispatch our loaded artists (simple objects) + dispatch({ + type: 'ARTISTS_LOADED', + artists: response.artists + }); + var album = Object.assign( {}, response, { - artists: helpers.asURIs(response.artists), + artists_uris: helpers.asURIs(response.artists), tracks: response.tracks.items, tracks_more: response.tracks.next, tracks_total: response.tracks.total } ) + // add our album to all the tracks + for (var i = 0; i < album.tracks.length; i++){ + album.tracks[i].album = { + name: album.name, + uri: album.uri + } + } + dispatch({ type: 'ALBUM_LOADED', + uri: album.uri, album: album }); @@ -854,6 +863,7 @@ export function getPlaylist( uri ){ dispatch({ type: 'PLAYLIST_LOADED', + uri: playlist.uri, playlist: playlist }) }) @@ -868,38 +878,15 @@ function loadNextPlaylistsBatch( dispatch, getState, playlists, lastResponse ){ loadNextPlaylistsBatch( dispatch, getState, playlists, response ) }); }else{ - - for( var i = 0; i < playlists.length; i++ ){ - var playlist = Object.assign( - {}, - playlists[i], - { - can_edit: (getState().spotify.authorized && getState().spotify.me && playlists[i].owner.id == getState().spotify.me.id), - tracks_total: playlists[i].tracks.total - } - ) - - // remove our tracklist. It'll overwrite any full records otherwise - delete playlist.tracks - - dispatch({ - type: 'PLAYLIST_LOADED', - playlist: playlist - }); - } - dispatch({ - type: 'LIBRARY_PLAYLISTS_LOADED', - uris: helpers.asURIs(playlists) + type: 'SPOTIFY_LIBRARY_PLAYLISTS_LOADED', + playlists: playlists }); } } export function getAllLibraryPlaylists(){ return (dispatch, getState) => { - - dispatch({ type: 'SPOTIFY_LIBRARY_PLAYLISTS_LOADED', data: false }); - sendRequest( dispatch, getState, 'me/playlists?limit=50' ) .then( response => { loadNextPlaylistsBatch( dispatch, getState, response.items, response ) diff --git a/src/js/services/spotify/middleware.js b/src/js/services/spotify/middleware.js index b8bb009e..68cd159e 100755 --- a/src/js/services/spotify/middleware.js +++ b/src/js/services/spotify/middleware.js @@ -93,6 +93,92 @@ const SpotifyMiddleware = (function(){ } break + case 'SPOTIFY_PLAYLIST_FOLLOWING_LOADED': + store.dispatch({ + type: 'PLAYLIST_LOADED', + uri: action.uri, + playlist: { + is_following: action.is_following + } + }); + break + + case 'SPOTIFY_ALBUM_FOLLOWING_LOADED': + store.dispatch({ + type: 'ALBUM_LOADED', + uri: action.uri, + album: { + is_following: action.is_following + } + }); + break + + case 'SPOTIFY_ARTIST_FOLLOWING_LOADED': + store.dispatch({ + type: 'ARTIST_LOADED', + uri: action.uri, + artist: { + is_following: action.is_following + } + }); + break + + case 'SPOTIFY_NEW_RELEASES_LOADED': + store.dispatch({ + type: 'ALBUMS_LOADED', + albums: action.data.albums.items + }); + store.dispatch({ + type: 'NEW_RELEASES_LOADED', + uris: helpers.asURIs(action.data.albums.items), + more: action.data.albums.next, + total: action.data.albums.total + }); + break + + case 'SPOTIFY_ARTIST_ALBUMS_LOADED': + store.dispatch({ + type: 'ALBUMS_LOADED', + albums: action.data.items + }); + store.dispatch({ + type: 'ARTIST_ALBUMS_LOADED', + uri: action.uri, + uris: helpers.asURIs(action.data.items), + more: action.data.next, + total: action.data.total + }); + break + + case 'SPOTIFY_LIBRARY_PLAYLISTS_LOADED': + var playlists = [] + for( var i = 0; i < action.playlists.length; i++ ){ + var playlist = Object.assign( + {}, + action.playlists[i], + { + can_edit: (store.getState().spotify.authorized && store.getState().spotify.me && action.playlists[i].owner.id == store.getState().spotify.me.id), + tracks_total: action.playlists[i].tracks.total + } + ) + + // remove our tracklist. It'll overwrite any full records otherwise + delete playlist.tracks + + playlists.push(playlist) + } + + store.dispatch({ + type: 'PLAYLISTS_LOADED', + playlists: playlists + }); + + store.dispatch({ + type: 'LIBRARY_PLAYLISTS_LOADED', + uris: helpers.asURIs(playlists) + }); + break + case 'SPOTIFY_LIBRARY_ARTISTS_LOADED': store.dispatch({ type: 'ARTISTS_LOADED', @@ -107,9 +193,7 @@ const SpotifyMiddleware = (function(){ break case 'SPOTIFY_LIBRARY_ALBUMS_LOADED': - var albums = [] - for (var i = 0; i < action.data.items.length; i++){ albums.push( Object.assign( diff --git a/src/js/services/ui/reducer.js b/src/js/services/ui/reducer.js index 9defb420..bdb39263 100755 --- a/src/js/services/ui/reducer.js +++ b/src/js/services/ui/reducer.js @@ -144,47 +144,16 @@ export default function reducer(ui = {}, action){ case 'ALBUM_LOADED': var albums = Object.assign([], ui.albums) - var album = Object.assign({}, action.album) - // if we already have one in our list, fetch it and update it - if (albums[action.album.uri]){ - album = Object.assign({}, albums[action.album.uri], action.album) + if (albums[action.uri]){ + var album = Object.assign({}, albums[action.uri], action.album) + }else{ + var album = Object.assign({}, action.album) } - albums[action.album.uri] = album + albums[action.uri] = album return Object.assign({}, ui, { albums: albums }); - case 'MOPIDY_ALBUM_LOADED': - if( !action.data ) return Object.assign({}, ui, { album: false }) - return Object.assign({}, ui, { album: action.data }); - - case 'LASTFM_ALBUM_LOADED': - if( !action.data.image ) return ui - - var album = Object.assign({}, ui.album, { images: action.data.image }) - return Object.assign({}, ui, { album: album }); - - case 'SPOTIFY_ALBUM_LOADED': - if( !action.data ) return Object.assign({}, ui, { album: false }) - - var album = Object.assign({}, { images: [] }, action.data, { - tracks: action.data.tracks.items, - tracks_total: action.data.tracks.total, - tracks_more: action.data.tracks.next - }) - return Object.assign({}, ui, { album: album }) - - case 'SPOTIFY_ALBUM_LOADED_MORE': - var album = Object.assign({}, ui.album, { - tracks: [ ...ui.album.tracks, ...action.data.items ], - tracks_more: action.data.next - }) - return Object.assign({}, ui, { album: album }); - - case 'ALBUM_FOLLOWING_LOADED': - var album = Object.assign({}, ui.album, { following: action.is_following }) - return Object.assign({}, ui, { album: album, following_loading: false }); - case 'LIBRARY_ALBUMS_LOADED': if (!action.uris){ return Object.assign({}, ui, { @@ -203,6 +172,24 @@ export default function reducer(ui = {}, action){ library_albums_total: action.total }); + case 'NEW_RELEASES_LOADED': + if (!action.uris){ + return Object.assign({}, ui, { + new_releases: null, + new_releases_more: null, + new_releases_total: null + }); + } + + var new_releases = [] + if (ui.new_releases) new_releases = Object.assign([], ui.new_releases) + + return Object.assign({}, ui, { + new_releases: [...new_releases, ...action.uris], + new_releases_more: action.more, + new_releases_total: action.total + }); + /** @@ -224,16 +211,34 @@ export default function reducer(ui = {}, action){ case 'ARTIST_LOADED': var artists = Object.assign([], ui.artists) - var artist = Object.assign({}, action.artist) - // if we already have one in our list, fetch it and update it - if (artists[action.artist.uri]){ - artist = Object.assign({}, artists[action.artist.uri], action.artist) + if (artists[action.uri]){ + var artist = Object.assign({}, artists[action.uri], action.artist) + }else{ + var artist = Object.assign({}, action.artist) } - artists[action.artist.uri] = artist + artists[action.uri] = artist return Object.assign({}, ui, { artists: artists }); + case 'ARTIST_ALBUMS_LOADED': + var artists = Object.assign([], ui.artists) + var albums_uris = [] + if (artists[action.uri].albums_uris) albums_uris = artists[action.uri].albums_uris + + var artist = Object.assign( + {}, + artists[action.uri], + { + albums_uris: [...albums_uris, ...action.uris], + albums_more: action.more, + albums_total: action.total + } + ) + artists[action.uri] = artist + return Object.assign({}, ui, { artists: artists }); + +/* case 'LASTFM_ARTIST_LOADED': if( !action.data.image ) return ui @@ -243,21 +248,7 @@ export default function reducer(ui = {}, action){ var artist = Object.assign({}, ui.artist, { images: images, bio: action.data.bio, listeners: parseInt(action.data.stats.listeners), on_tour: action.data.ontour }, ) return Object.assign({}, ui, { artist: artist }); - - case 'SPOTIFY_ARTIST_LOADED': - if( !action.data ) return Object.assign({}, ui, { artist: false }) - return Object.assign({}, ui, { artist: action.data }) - - case 'SPOTIFY_ARTIST_ALBUMS_LOADED_MORE': - var artist = Object.assign({}, ui.artist, { - albums: [ ...ui.artist.albums, ...action.data.items ], - albums_more: action.data.next - }) - return Object.assign({}, ui, { artist: artist }); - - case 'ARTIST_FOLLOWING_LOADED': - var artist = Object.assign({}, ui.artist, { following: action.is_following }) - return Object.assign({}, ui, { artist: artist, following_loading: false }); + */ case 'LIBRARY_ARTISTS_LOADED': if (!action.uris){ @@ -305,14 +296,27 @@ export default function reducer(ui = {}, action){ case 'PLAYLIST_LOADED': case 'PLAYLIST_UPDATED': var playlists = Object.assign([], ui.playlists) - var playlist = Object.assign({}, action.playlist) - // if we already have one in our list, fetch it and update it - if (playlists[action.playlist.uri]){ - playlist = Object.assign({}, playlists[action.playlist.uri], action.playlist) + if (playlists[action.uri]){ + var playlist = Object.assign({}, playlists[action.uri], action.playlist) + }else{ + var playlist = Object.assign({}, action.playlist) + } + + playlists[action.uri] = playlist + return Object.assign({}, ui, { playlists: playlists }); + + case 'PLAYLISTS_LOADED': + var playlists = Object.assign([], ui.playlists) + + for (var i = 0; i < action.playlists.length; i++){ + var playlist = action.playlists[i] + if (typeof(playlists[playlist.uri]) !== 'undefined'){ + artist = Object.assign({}, playlists[playlist.uri], playlist) + } + playlists[playlist.uri] = playlist } - playlists[action.playlist.uri] = playlist return Object.assign({}, ui, { playlists: playlists }); case 'MOPIDY_PLAYLIST_LOADED': diff --git a/src/js/views/Album.js b/src/js/views/Album.js index 5054565e..8564e03b 100755 --- a/src/js/views/Album.js +++ b/src/js/views/Album.js @@ -25,7 +25,7 @@ class Album extends React.Component{ } componentDidMount(){ - this.loadAlbum(); + this.loadAlbum() } componentWillReceiveProps( nextProps ){ @@ -43,13 +43,14 @@ class Album extends React.Component{ } loadAlbum( props = this.props ){ - // if we've already loaded the full version of this album, halt! - if (this.props.album && this.props.album.tracks) return false - switch( helpers.uriSource( props.params.uri ) ){ case 'spotify': - this.props.spotifyActions.getAlbum( props.params.uri ); + if (props.album && props.album.tracks && props.album.artists_uris){ + console.info('Loading album from index') + }else{ + this.props.spotifyActions.getAlbum( props.params.uri ); + } break; case 'local': @@ -72,9 +73,9 @@ class Album extends React.Component{ if( !this.props.album ) return null var artists = [] - if (this.props.album.artists){ - for (var i = 0; i < this.props.album.artists.length; i++){ - var uri = this.props.album.artists[i] + 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]) } @@ -90,7 +91,7 @@ class Album extends React.Component{