From eaf86e1848394d55fccb312bc050bf4e02c58e45 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Sat, 12 Aug 2017 23:01:55 +1200 Subject: [PATCH] Moving libraries into each provider for better granularity; Loading all artists (larger than expected) --- src/js/services/core/middleware.js | 3 + src/js/services/mopidy/middleware.js | 18 ++- src/js/services/mopidy/reducer.js | 29 +++++ src/js/services/spotify/actions.js | 138 ++++++++++++++--------- src/js/services/spotify/middleware.js | 32 +++--- src/js/services/spotify/reducer.js | 96 +++++----------- src/js/views/library/LibraryAlbums.js | 89 +++++++++------ src/js/views/library/LibraryArtists.js | 58 ++++------ src/js/views/library/LibraryPlaylists.js | 94 ++++++++------- 9 files changed, 302 insertions(+), 255 deletions(-) diff --git a/src/js/services/core/middleware.js b/src/js/services/core/middleware.js index 48bce9b1..e2e8f129 100755 --- a/src/js/services/core/middleware.js +++ b/src/js/services/core/middleware.js @@ -254,6 +254,7 @@ const CoreMiddleware = (function(){ next(action) break + // Get assets from all of our providers case 'GET_LIBRARY_PLAYLISTS': if (store.getState().spotify.connected){ store.dispatch(spotifyActions.getLibraryPlaylists()) @@ -264,6 +265,7 @@ const CoreMiddleware = (function(){ next(action) break + // Get assets from all of our providers case 'GET_LIBRARY_ALBUMS': if (store.getState().spotify.connected){ store.dispatch(spotifyActions.getLibraryAlbums()) @@ -274,6 +276,7 @@ const CoreMiddleware = (function(){ next(action) break + // Get assets from all of our providers case 'GET_LIBRARY_ARTISTS': if (store.getState().spotify.connected){ store.dispatch(spotifyActions.getLibraryArtists()) diff --git a/src/js/services/mopidy/middleware.js b/src/js/services/mopidy/middleware.js index 391329a6..7756f0a4 100755 --- a/src/js/services/mopidy/middleware.js +++ b/src/js/services/mopidy/middleware.js @@ -592,12 +592,20 @@ const MopidyMiddleware = (function(){ // drop in our URI list var playlist_uris = helpers.arrayOf('uri',response) + var playlist_uris_filtered = [] - store.dispatch({ type: 'LIBRARY_PLAYLISTS_LOADED', uris: playlist_uris }); + // Remove any Spotify playlists. These will be handled by our Spotify API + for (var i = 0; i < playlist_uris.length; i++){ + if (helpers.uriSource(playlist_uris[i]) != 'spotify'){ + playlist_uris_filtered.push(playlist_uris[i]) + } + } + + store.dispatch({ type: 'MOPIDY_LIBRARY_PLAYLISTS_LOADED', uris: playlist_uris_filtered }); // get the full playlist objects - for (var i = 0; i < response.length; i++ ){ - instruct( socket, store, 'playlists.lookup', { uri: response[i].uri }) + for (var i = 0; i < playlist_uris_filtered.length; i++ ){ + instruct( socket, store, 'playlists.lookup', { uri: playlist_uris_filtered[i] }) .then( response => { var source = helpers.uriSource(response.uri) var playlist = Object.assign( @@ -850,7 +858,7 @@ const MopidyMiddleware = (function(){ var uris = helpers.arrayOf('uri',response) store.dispatch({ - type: 'LIBRARY_ALBUMS_LOADED', + type: 'MOPIDY_LIBRARY_ALBUMS_LOADED', uris: uris }); @@ -860,8 +868,6 @@ const MopidyMiddleware = (function(){ break; case 'MOPIDY_LIBRARY_ALBUMS_PROCESSOR': - console.log(action) - if (store.getState().ui.processes['MOPIDY_LIBRARY_ALBUMS_PROCESSOR'] !== undefined){ var processor = store.getState().ui.processes['MOPIDY_LIBRARY_ALBUMS_PROCESSOR'] diff --git a/src/js/services/mopidy/reducer.js b/src/js/services/mopidy/reducer.js index a3b75df8..7a1e5092 100755 --- a/src/js/services/mopidy/reducer.js +++ b/src/js/services/mopidy/reducer.js @@ -122,6 +122,35 @@ export default function reducer(mopidy = {}, action){ enqueue_uris_batches: batches }); + + /** + * Library + **/ + + case 'MOPIDY_LIBRARY_PLAYLISTS_LOADED': + if (mopidy.library_playlists){ + var uris = [...mopidy.library_playlists,...action.uris] + } else { + var uris = action.uris + } + return Object.assign({}, mopidy, { library_playlists: uris }) + + case 'MOPIDY_LIBRARY_ARTISTS_LOADED': + if (mopidy.library_artists){ + var uris = [...mopidy.library_artists,...action.uris] + } else { + var uris = action.uris + } + return Object.assign({}, mopidy, { library_artists: uris }) + + case 'MOPIDY_LIBRARY_ALBUMS_LOADED': + if (mopidy.library_albums){ + var uris = [...mopidy.library_albums,...action.uris] + } else { + var uris = action.uris + } + return Object.assign({}, mopidy, { library_albums: uris }) + default: return mopidy } diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js index 6915adde..9eaebf69 100755 --- a/src/js/services/spotify/actions.js +++ b/src/js/services/spotify/actions.js @@ -912,19 +912,6 @@ export function getArtists( uris ){ } -export function getLibraryArtists(){ - return (dispatch, getState) => { - sendRequest( dispatch, getState, 'me/following?type=artist&limit=50' ) - .then( response => { - dispatch({ - type: 'SPOTIFY_LIBRARY_ARTISTS_LOADED', - data: response - }) - }); - } -} - - export function playArtistTopTracks(uri){ return (dispatch, getState) => { const artists = getState().ui.artists @@ -1305,54 +1292,13 @@ export function reorderPlaylistTracks( uri, range_start, range_length, insert_be **/ -/** - * ALbums - **/ - -export function getLibraryAlbums(){ - return (dispatch, getState) => { - dispatch(uiActions.startProcess('SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR','Loading Spotify library albums', {next: 'me/albums?limit=50'})) - } -} - -export function getLibraryAlbumsProcessor(data){ - return (dispatch, getState) => { - sendRequest(dispatch, getState, data.next) - .then( response => { - - dispatch({ - type: 'SPOTIFY_LIBRARY_ALBUMS_LOADED', - albums: response.items - }) - - // Check to see if we've been cancelled - if (getState().ui.processes['SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR'] !== undefined){ - var processor = getState().ui.processes['SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR'] - - if (processor.cancelling){ - dispatch(uiActions.processFinished('SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR')) - return false - } - } - - // We got a next link, so we've got more work to be done - if (response.next){ - dispatch(uiActions.runProcess('SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR', {next: response.next})) - } else { - dispatch(uiActions.processFinished('SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR')) - } - }); - } -} - - /** * Playlists **/ export function getLibraryPlaylists(){ return (dispatch, getState) => { - dispatch(uiActions.startProcess('SPOTIFY_GET_LIBRARY_PLAYLISTS_PROCESSOR','Loading Spotify library playlists', {next: 'me/playlists?limit=50'})) + dispatch(uiActions.startProcess('SPOTIFY_GET_LIBRARY_PLAYLISTS_PROCESSOR','Loading Spotify playlists', {next: 'me/playlists?limit=50'})) } } @@ -1384,4 +1330,86 @@ export function getLibraryPlaylistsProcessor(data){ } }); } +} + + +/** + * Artists + **/ + +export function getLibraryArtists(){ + return (dispatch, getState) => { + dispatch(uiActions.startProcess('SPOTIFY_GET_LIBRARY_ARTISTS_PROCESSOR','Loading Spotify artists', {next: 'me/following?type=artist&limit=50'})) + } +} + +export function getLibraryArtistsProcessor(data){ + return (dispatch, getState) => { + sendRequest(dispatch, getState, data.next) + .then( response => { + + dispatch({ + type: 'SPOTIFY_LIBRARY_ARTISTS_LOADED', + artists: response.artists.items + }) + + // Check to see if we've been cancelled + if (getState().ui.processes['SPOTIFY_GET_LIBRARY_ARTISTS_PROCESSOR'] !== undefined){ + var processor = getState().ui.processes['SPOTIFY_GET_LIBRARY_ARTISTS_PROCESSOR'] + + if (processor.cancelling){ + dispatch(uiActions.processFinished('SPOTIFY_GET_LIBRARY_ARTISTS_PROCESSOR')) + return false + } + } + + // We got a next link, so we've got more work to be done + if (response.artists.next){ + dispatch(uiActions.runProcess('SPOTIFY_GET_LIBRARY_ARTISTS_PROCESSOR', {next: response.artists.next})) + } else { + dispatch(uiActions.processFinished('SPOTIFY_GET_LIBRARY_ARTISTS_PROCESSOR')) + } + }); + } +} + + +/** + * ALbums + **/ + +export function getLibraryAlbums(){ + return (dispatch, getState) => { + dispatch(uiActions.startProcess('SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR','Loading Spotify albums', {next: 'me/albums?limit=50'})) + } +} + +export function getLibraryAlbumsProcessor(data){ + return (dispatch, getState) => { + sendRequest(dispatch, getState, data.next) + .then( response => { + + dispatch({ + type: 'SPOTIFY_LIBRARY_ALBUMS_LOADED', + albums: response.items + }) + + // Check to see if we've been cancelled + if (getState().ui.processes['SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR'] !== undefined){ + var processor = getState().ui.processes['SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR'] + + if (processor.cancelling){ + dispatch(uiActions.processFinished('SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR')) + return false + } + } + + // We got a next link, so we've got more work to be done + if (response.next){ + dispatch(uiActions.runProcess('SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR', {next: response.next})) + } else { + dispatch(uiActions.processFinished('SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR')) + } + }); + } } \ No newline at end of file diff --git a/src/js/services/spotify/middleware.js b/src/js/services/spotify/middleware.js index a282d0bb..6c8e10bc 100755 --- a/src/js/services/spotify/middleware.js +++ b/src/js/services/spotify/middleware.js @@ -208,19 +208,22 @@ const SpotifyMiddleware = (function(){ playlists: playlists }); - store.dispatch({ - type: 'LIBRARY_PLAYLISTS_LOADED', - uris: helpers.arrayOf('uri',playlists) - }); + // Append our action with the uris. This gets handed down to subsequent middleware and our reducer. + action.uris = helpers.arrayOf('uri',playlists) + next(action) + break + + case 'SPOTIFY_GET_LIBRARY_ARTISTS_PROCESSOR': + store.dispatch(spotifyActions.getLibraryArtistsProcessor(action.data)) break case 'SPOTIFY_LIBRARY_ARTISTS_LOADED': var artists = [] - for (var i = 0; i < action.data.artists.items.length; i++){ + for (var i = 0; i < action.artists.length; i++){ artists.push( Object.assign( {}, - action.data.artists.items[i], + action.artists[i], { source: 'spotify', in_library: true // assumed because we asked for library items @@ -232,12 +235,10 @@ const SpotifyMiddleware = (function(){ type: 'ARTISTS_LOADED', artists: artists }); - store.dispatch({ - type: 'LIBRARY_ARTISTS_LOADED', - uris: helpers.arrayOf('uri',artists), - more: action.data.artists.next, - total: action.data.artists.total - }); + + // Append our action with the uris. This gets handed down to subsequent middleware and our reducer. + action.uris = helpers.arrayOf('uri',artists) + next(action) break case 'SPOTIFY_GET_LIBRARY_ALBUMS_PROCESSOR': @@ -268,10 +269,9 @@ const SpotifyMiddleware = (function(){ albums: albums }); - store.dispatch({ - type: 'LIBRARY_ALBUMS_LOADED', - uris: helpers.arrayOf('uri',albums) - }); + // Append our action with the uris. This gets handed down to subsequent middleware and our reducer. + action.uris = helpers.arrayOf('uri',albums) + next(action) break case 'SPOTIFY_FAVORITES_LOADED': diff --git a/src/js/services/spotify/reducer.js b/src/js/services/spotify/reducer.js index 60e14a33..c0822506 100755 --- a/src/js/services/spotify/reducer.js +++ b/src/js/services/spotify/reducer.js @@ -73,73 +73,6 @@ export default function reducer(spotify = {}, action){ case 'SPOTIFY_ME_LOADED': return Object.assign({}, spotify, { me: action.data }) - case 'SPOTIFY_LIBRARY_ALBUMS_LOADED': - if( !action.data ) return Object.assign({}, spotify) - var albums = [] - for( var i = 0; i < action.data.items.length; i++ ){ - albums.push( Object.assign( - {}, - action.data.items[i].album, - { - added_at: action.data.items[i].added_at - } - )) - } - console.log(action) - return Object.assign({}, spotify, { - library_albums: albums, - library_albums_spotify_more: action.data.next - }) - - case 'SPOTIFY_LIBRARY_ALBUMS_LOADED_MORE': - var albums = [] - for( var i = 0; i < action.data.items.length; i++ ){ - albums.push( Object.assign( - {}, - action.data.items[i].album, - { - added_at: action.data.items[i].added_at - } - )) - } - return Object.assign({}, spotify, { - library_albums: [...spotify.library_albums, ...albums ], - library_albums_spotify_more: action.data.next - }) - - case 'SPOTIFY_LIBRARY_TRACKS_LOADED': - if( !action.data ) return Object.assign({}, spotify) - var tracks = Object.assign([], action.data.items) - for( var i = 0; i < tracks.length; i++ ){ - tracks[i] = Object.assign( - {}, - tracks[i].track, - { - added_at: tracks[i].added_at - } - ) - } - return Object.assign({}, spotify, { - library_tracks: tracks, - library_tracks_more: action.data.next - }) - - case 'SPOTIFY_LIBRARY_TRACKS_LOADED_MORE': - var tracks = Object.assign([], action.data.items) - for( var i = 0; i < tracks.length; i++ ){ - tracks[i] = Object.assign( - {}, - tracks[i].track, - { - added_at: tracks[i].added_at - } - ) - } - return Object.assign({}, spotify, { - library_tracks: [...spotify.library_tracks, ...tracks], - library_tracks_more: action.data.next - }) - case 'SPOTIFY_FEATURED_PLAYLISTS_LOADED': return Object.assign({}, spotify, { featured_playlists: action.data }) @@ -212,6 +145,35 @@ export default function reducer(spotify = {}, action){ autocomplete_results: autocomplete_results }) + + /** + * Library + **/ + + case 'SPOTIFY_LIBRARY_PLAYLISTS_LOADED': + if (spotify.library_playlists){ + var uris = [...spotify.library_playlists,...action.uris] + } else { + var uris = action.uris + } + return Object.assign({}, spotify, { library_playlists: uris }) + + case 'SPOTIFY_LIBRARY_ARTISTS_LOADED': + if (spotify.library_artists){ + var uris = [...spotify.library_artists,...action.uris] + } else { + var uris = action.uris + } + return Object.assign({}, spotify, { library_artists: uris }) + + case 'SPOTIFY_LIBRARY_ALBUMS_LOADED': + if (spotify.library_albums){ + var uris = [...spotify.library_albums,...action.uris] + } else { + var uris = action.uris + } + return Object.assign({}, spotify, { library_albums: uris }) + default: return spotify } diff --git a/src/js/views/library/LibraryAlbums.js b/src/js/views/library/LibraryAlbums.js index 770c7536..aa5ca37d 100755 --- a/src/js/views/library/LibraryAlbums.js +++ b/src/js/views/library/LibraryAlbums.js @@ -26,17 +26,40 @@ class LibraryAlbums extends React.Component{ } componentDidMount(){ - if (!this.props.library_albums){ - this.props.coreActions.getLibraryAlbums() + if (!this.props.mopidy_library_albums && this.props.mopidy_connected && (this.props.filter == 'all' || this.props.filter == 'local')){ + this.props.mopidyActions.getLibraryAlbums() + } + + if (!this.props.spotify_library_albums && this.props.spotify_connected && (this.props.filter == 'all' || this.props.filter == 'spotify')){ + this.props.spotifyActions.getLibraryAlbums() } } componentWillReceiveProps(newProps){ - if (!this.props.spotify_connected && newProps.spotify_connected){ - this.props.spotifyActions.getLibraryAlbums() + if (newProps.mopidy_connected && (newProps.filter == 'all' || newProps.filter == 'local')){ + + // We've just connected + if (!this.props.mopidy_connected){ + this.props.mopidyActions.getLibraryAlbums() + } + + // Filter changed, but we haven't got this provider's library yet + if (this.props.filter != 'all' && this.props.filter != 'local' && !newProps.mopidy_library_albums){ + this.props.mopidyActions.getLibraryAlbums() + } } - if (!this.props.mopidy_connected && newProps.mopidy_connected){ - this.props.mopidyActions.getLibraryAlbums() + + if (newProps.spotify_connected && (newProps.filter == 'all' || newProps.filter == 'spotify')){ + + // We've just connected + if (!this.props.spotify_connected){ + this.props.spotifyActions.getLibraryAlbums() + } + + // Filter changed, but we haven't got this provider's library yet + if (this.props.filter != 'all' && this.props.filter != 'spotify' && !newProps.spotify_library_albums){ + this.props.spotifyActions.getLibraryAlbums() + } } } @@ -157,10 +180,24 @@ class LibraryAlbums extends React.Component{ render(){ var albums = [] - if (this.props.library_albums && this.props.albums){ - for (var i = 0; i < this.props.library_albums.length; i++){ - var uri = this.props.library_albums[i] + // Spotify library items + if (this.props.spotify_library_albums && (this.props.filter == 'all' || this.props.filter == 'spotify')){ + for (var i = 0; i < this.props.spotify_library_albums.length; i++){ + var uri = this.props.spotify_library_albums[i] + if (this.props.albums.hasOwnProperty(uri)){ + albums.push(this.props.albums[uri]) + } + } + } + + // Mopidy library items + if (this.props.mopidy_library_albums && (this.props.filter == 'all' || this.props.filter == 'local')){ + for (var i = 0; i < this.props.mopidy_library_albums.length; i++){ + + // Construct item placeholder. This is used as Mopidy needs to + // lookup ref objects to get the full object which can take some time + var uri = this.props.mopidy_library_albums[i] var source = helpers.uriSource(uri) var album = { uri: uri, @@ -171,29 +208,12 @@ class LibraryAlbums extends React.Component{ album = this.props.albums[uri] } - switch (this.props.filter){ - - case 'spotify': - if (source == 'spotify'){ - albums.push(album) - } - break - - case 'local': - if (source == 'local'){ - albums.push(album) - } - break - - default: - albums.push(album) - break - } + albums.push(album) } + } - if( this.props.sort ){ - albums = helpers.sortItems(albums, this.props.sort, this.props.sort_reverse) - } + if (this.props.sort){ + albums = helpers.sortItems(albums, this.props.sort, this.props.sort_reverse) } var filter_options = [ @@ -259,11 +279,7 @@ class LibraryAlbums extends React.Component{
- { this.renderView(albums) } - this.loadMoreSpotify()} - /> + {this.renderView(albums)}
@@ -284,7 +300,8 @@ const mapStateToProps = (state, ownProps) => { spotify_connected: state.spotify.connected, load_queue: state.ui.load_queue, albums: state.core.albums, - library_albums: state.core.library_albums, + spotify_library_albums: state.spotify.library_albums, + mopidy_library_albums: state.mopidy.library_albums, view: state.ui.library_albums_view, filter: (state.ui.library_albums_filter ? state.ui.library_albums_filter : 'all'), sort: (state.ui.library_albums_sort ? state.ui.library_albums_sort : 'name'), diff --git a/src/js/views/library/LibraryArtists.js b/src/js/views/library/LibraryArtists.js index d87d82af..74ae10b6 100755 --- a/src/js/views/library/LibraryArtists.js +++ b/src/js/views/library/LibraryArtists.js @@ -21,6 +21,22 @@ class LibraryArtists extends React.Component{ super(props); } + componentDidMount(){ + if (!this.props.spotify_library_artists && this.props.spotify_connected){ + this.props.spotifyActions.getLibraryArtists() + } + } + + componentWillReceiveProps(newProps){ + if (newProps.spotify_connected){ + + // We've just connected + if (!this.props.spotify_connected){ + this.props.spotifyActions.getLibraryArtists() + } + } + } + handleContextMenu(e,item){ var data = { e: e, @@ -31,16 +47,6 @@ class LibraryArtists extends React.Component{ this.props.uiActions.showContextMenu(data) } - componentDidMount(){ - if (!this.props.library_artists_started){ - this.props.spotifyActions.getLibraryArtists(); - } - } - - loadMore(){ - this.props.spotifyActions.getURL( this.props.library_artists_more, 'SPOTIFY_LIBRARY_ARTISTS_LOADED' ); - } - setSort(value){ var reverse = false if( this.props.sort == value ) reverse = !this.props.sort_reverse @@ -90,31 +96,20 @@ class LibraryArtists extends React.Component{ } render(){ - if (helpers.isLoading(this.props.load_queue,['spotify_me/following?type=artist'])){ - return ( -
-
-
-
-
-
- ) - } - var artists = [] - if (this.props.library_artists && this.props.artists){ - for (var i = 0; i < this.props.library_artists.length; i++){ - var uri = this.props.library_artists[i] + + // Spotify library items + if (this.props.spotify_library_artists){ + for (var i = 0; i < this.props.spotify_library_artists.length; i++){ + var uri = this.props.spotify_library_artists[i] if (this.props.artists.hasOwnProperty(uri)){ artists.push(this.props.artists[uri]) } } - - if( this.props.sort ){ - artists = helpers.sortItems(artists, this.props.sort, this.props.sort_reverse) - } } + artists = helpers.sortItems(artists, this.props.sort, this.props.sort_reverse) + var view_options = [ { label: 'Thumbnails', @@ -167,12 +162,9 @@ class LibraryArtists extends React.Component{ const mapStateToProps = (state, ownProps) => { return { - load_queue: state.ui.load_queue, + spotify_connected: state.spotify.connected, + spotify_library_artists: state.spotify.library_artists, artists: state.core.artists, - library_artists: state.core.library_artists, - library_artists_started: state.core.library_artists_started, - library_artists_more: state.core.library_artists_more, - library_artists_started: state.core.library_artists_started, sort: (state.ui.library_artists_sort ? state.ui.library_artists_sort : 'name'), sort_reverse: (state.ui.library_artists_sort_reverse ? true : false), view: state.core.library_artists_view diff --git a/src/js/views/library/LibraryPlaylists.js b/src/js/views/library/LibraryPlaylists.js index 0f9d8a55..fb699c38 100755 --- a/src/js/views/library/LibraryPlaylists.js +++ b/src/js/views/library/LibraryPlaylists.js @@ -23,20 +23,40 @@ class LibraryPlaylists extends React.Component{ } componentDidMount(){ - if (!this.props.library_playlists){ - if (this.props.spotify_connected){ - this.props.coreActions.getLibraryPlaylists() - } + if (!this.props.mopidy_library_playlists && this.props.mopidy_connected && (this.props.filter == 'all' || this.props.filter == 'local')){ + this.props.mopidyActions.getLibraryPlaylists() + } + + if (!this.props.spotify_library_playlists && this.props.spotify_connected && (this.props.filter == 'all' || this.props.filter == 'spotify')){ + this.props.spotifyActions.getLibraryPlaylists() } } componentWillReceiveProps(newProps){ - if (!this.props.spotify_connected && newProps.spotify_connected){ - this.props.spotifyActions.getLibraryPlaylists() + if (newProps.mopidy_connected && (newProps.filter == 'all' || newProps.filter == 'local')){ + + // We've just connected + if (!this.props.mopidy_connected){ + this.props.mopidyActions.getLibraryPlaylists() + } + + // Filter changed, but we haven't got this provider's library yet + if (this.props.filter != 'all' && this.props.filter != 'local' && !newProps.mopidy_library_playlists){ + this.props.mopidyActions.getLibraryPlaylists() + } } - if (!this.props.mopidy_connected && newProps.mopidy_connected){ - this.props.mopidyActions.getLibraryPlaylists() + if (newProps.spotify_connected && (newProps.filter == 'all' || newProps.filter == 'spotify')){ + + // We've just connected + if (!this.props.spotify_connected){ + this.props.spotifyActions.getLibraryPlaylists() + } + + // Filter changed, but we haven't got this provider's library yet + if (this.props.filter != 'all' && this.props.filter != 'spotify' && !newProps.spotify_library_playlists){ + this.props.spotifyActions.getLibraryPlaylists() + } } } @@ -62,43 +82,32 @@ class LibraryPlaylists extends React.Component{ } renderView(){ - if (!this.props.library_playlists || !this.props.playlists ){ - return null - } - var playlists = [] - for (var i = 0; i < this.props.library_playlists.length; i++){ - var uri = this.props.library_playlists[i] - var owner_id = helpers.getFromUri('playlistowner',uri) - if (this.props.playlists.hasOwnProperty(uri)){ - - switch (this.props.filter){ - - case 'only_mine': - if (this.props.me_id && owner_id == this.props.me_id){ - playlists.push(this.props.playlists[uri]) - } - break - - case 'only_others': - if (!this.props.me_id || owner_id != this.props.me_id){ - playlists.push(this.props.playlists[uri]) - } - break - - default: - playlists.push(this.props.playlists[uri]) - break + // Spotify library items + if (this.props.spotify_library_playlists && (this.props.filter == 'all' || this.props.filter == 'spotify')){ + for (var i = 0; i < this.props.spotify_library_playlists.length; i++){ + var uri = this.props.spotify_library_playlists[i] + if (this.props.playlists.hasOwnProperty(uri)){ + playlists.push(this.props.playlists[uri]) } } } - if( this.props.sort ){ - playlists = helpers.sortItems(playlists, this.props.sort, this.props.sort_reverse) + // Mopidy library items + if (this.props.mopidy_library_playlists && (this.props.filter == 'all' || this.props.filter == 'local')){ + for (var i = 0; i < this.props.mopidy_library_playlists.length; i++){ + var uri = this.props.mopidy_library_playlists[i] + if (this.props.playlists.hasOwnProperty(uri)){ + playlists.push(this.props.playlists[uri]) + } + } } - if( this.props.view == 'list' ){ + playlists = helpers.sortItems(playlists, this.props.sort, this.props.sort_reverse) + playlists = helpers.removeDuplicates(playlists) + + if (this.props.view == 'list'){ if (this.props.slim_mode){ var columns = [ { @@ -164,12 +173,12 @@ class LibraryPlaylists extends React.Component{ label: 'All' }, { - value: 'only_mine', - label: 'Owned by me' + value: 'local', + label: 'Local' }, { - value: 'only_others', - label: 'I\'m following' + value: 'spotify', + label: 'Spotify' } ] @@ -239,6 +248,8 @@ const mapStateToProps = (state, ownProps) => { return { mopidy_connected: state.mopidy.connected, spotify_connected: state.spotify.connected, + mopidy_library_playlists: state.mopidy.library_playlists, + spotify_library_playlists: state.spotify.library_playlists, slim_mode: state.ui.slim_mode, load_queue: state.ui.load_queue, me_id: (state.spotify.me ? state.spotify.me.id : (state.ui.config && state.ui.config.spotify_username ? state.ui.config.spotify_username : false)), @@ -246,7 +257,6 @@ const mapStateToProps = (state, ownProps) => { filter: (state.ui.library_playlists_filter ? state.ui.library_playlists_filter : 'all'), sort: (state.ui.library_playlists_sort ? state.ui.library_playlists_sort : 'name'), sort_reverse: (state.ui.library_playlists_sort_reverse ? true : false), - library_playlists: state.core.library_playlists, playlists: state.core.playlists } }