From cb41a24dbd5f31ac0112e977ac681730144d871d Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Mon, 16 Jan 2017 18:31:06 +1300 Subject: [PATCH] Searching --- src/js/bootstrap.js | 8 --- src/js/helpers.js | 19 ++++++ src/js/services/localstorage/middleware.js | 4 +- src/js/services/mopidy/actions.js | 6 +- src/js/services/spotify/actions.js | 55 +++++++++++++---- src/js/services/ui/reducer.js | 70 +++++++++++++++------- src/js/views/Debug.js | 14 +++++ src/js/views/Search.js | 58 +++++++++++++++--- 8 files changed, 182 insertions(+), 52 deletions(-) diff --git a/src/js/bootstrap.js b/src/js/bootstrap.js index 2ba1661b..87a29d61 100755 --- a/src/js/bootstrap.js +++ b/src/js/bootstrap.js @@ -59,14 +59,6 @@ var initialState = { }, current_tracklist: [], current_tltrack: false, - search_results: { - artists: [], - albums: [], - playlists: [], - tracks: [] - }, - library_playlists: [], - playlists: [], notifications: [] } }; diff --git a/src/js/helpers.js b/src/js/helpers.js index 15e74f08..3cbe09fa 100755 --- a/src/js/helpers.js +++ b/src/js/helpers.js @@ -248,6 +248,25 @@ export let mergeDuplicates = function(list, key){ return clean_list; } + +/** + * Remove duplicate items in a simple array + * + * @param list Array the unclean array + **/ +export let removeDuplicates = function(array){ + var unique = []; + + for( var i in array ){ + if (unique.indexOf(array[i]) <= -1 ){ + unique.push(array[i]) + } + } + + return unique; +} + + /** * Convert a list of indexes to a useable range * We ignore stragglers, and only attend to the first 'bunch' of consecutive indexes diff --git a/src/js/services/localstorage/middleware.js b/src/js/services/localstorage/middleware.js index b04cc042..1b7b6925 100755 --- a/src/js/services/localstorage/middleware.js +++ b/src/js/services/localstorage/middleware.js @@ -12,7 +12,9 @@ const localstorageMiddleware = (function(){ // append our state to a global variable. This gives us access to debug the store at any point window._store = store - //console.log(action) + + // if debug enabled + if (store.getState().ui.log_actions) console.log(action) switch( action.type ){ diff --git a/src/js/services/mopidy/actions.js b/src/js/services/mopidy/actions.js index d06bac5b..dc6053bb 100755 --- a/src/js/services/mopidy/actions.js +++ b/src/js/services/mopidy/actions.js @@ -211,11 +211,15 @@ export function getSearchResults(query, backends = null, fields = ['any']){ for( var i = 0; i < fields.length; i++ ){ queryObj[fields[i]] = [query]; } - + return { + type: 'NOTHING' + } + /* return { type: 'MOPIDY_INSTRUCT', call: 'library.search', value: { query: queryObj, uris: backends } } + */ } \ No newline at end of file diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js index 202f6e79..a0d50d8d 100755 --- a/src/js/services/spotify/actions.js +++ b/src/js/services/spotify/actions.js @@ -317,9 +317,9 @@ export function getCategory( id ){ ).then( ( category_response, playlists_response ) => { + var playlists = [] for (var i = 0; i < playlists_response.playlists.items.length; i++){ - - var playlist = Object.assign( + playlists.push(Object.assign( {}, playlists_response.playlists.items[i], { @@ -327,14 +327,14 @@ export function getCategory( id ){ tracks_more: null, tracks_total: playlists_response.playlists.items[i].tracks.total } - ) - - dispatch({ - type: 'PLAYLIST_LOADED', - playlist: playlist - }); + )) } + dispatch({ + type: 'PLAYLISTS_LOADED', + playlists: playlists + }); + var category = Object.assign( {}, category_response, @@ -382,7 +382,7 @@ export function getURL( url, action_name, uri = false ){ export function getSearchResults( query, type = 'album,artist,playlist,track', limit = 50, offset = 0 ){ return (dispatch, getState) => { - dispatch({ type: 'SPOTIFY_SEARCH_RESULTS_LOADED', data: false }); + dispatch({ type: 'SEARCH_RESULTS_LOADED', reset: true }); var url = 'search?q='+query url += '&type='+type @@ -392,9 +392,42 @@ export function getSearchResults( query, type = 'album,artist,playlist,track', l sendRequest( dispatch, getState, url ) .then( response => { + dispatch({ - type: 'SPOTIFY_SEARCH_RESULTS_LOADED', - data: response + type: 'ARTISTS_LOADED', + artists: response.artists.items + }); + + dispatch({ + type: 'ALBUMS_LOADED', + albums: response.albums.items + }); + + var playlists = [] + for (var i = 0; i < response.playlists.items.length; i++){ + playlists.push(Object.assign( + {}, + response.playlists.items[i], + { + can_edit: (getState().spotify.me && response.playlists.items[i].owner.id == getState().spotify.me.id), + tracks_total: response.playlists.items[i].tracks.total + } + )) + } + dispatch({ + type: 'PLAYLISTS_LOADED', + playlists: playlists + }); + + dispatch({ + type: 'SEARCH_RESULTS_LOADED', + playlists_uris: helpers.asURIs(playlists), + playlists_more: response.playlists.next, + artists_uris: helpers.asURIs(response.artists.items), + artists_more: response.artists.next, + albums_uris: helpers.asURIs(response.albums.items), + albums_more: response.albums.next, + tracks: response.tracks }); }); } diff --git a/src/js/services/ui/reducer.js b/src/js/services/ui/reducer.js index 77498346..8eba6f85 100755 --- a/src/js/services/ui/reducer.js +++ b/src/js/services/ui/reducer.js @@ -142,7 +142,6 @@ export default function reducer(ui = {}, action){ return Object.assign({}, ui, { albums: albums }); case 'ALBUMS_LOADED': - console.log(action) var albums = Object.assign([], ui.albums) for (var i = 0; i < action.albums.length; i++){ @@ -202,7 +201,6 @@ export default function reducer(ui = {}, action){ **/ case 'ARTIST_LOADED': - console.log(action) var artists = Object.assign([], ui.artists) if (artists[action.uri]){ @@ -391,11 +389,16 @@ export default function reducer(ui = {}, action){ return Object.assign({}, ui, { playlists: playlists }); case 'LIBRARY_PLAYLISTS_LOADED': - var library_playlists = [] - if (ui.library_playlists) library_playlists = ui.library_playlists + if (ui.library_playlists){ + var library_playlists = [...ui.library_playlists, ...action.uris] + }else{ + var library_playlists = action.uris + } + + library_playlists = helpers.removeDuplicates(library_playlists) return Object.assign({}, ui, { - library_playlists: [...library_playlists, ...action.uris] + library_playlists: library_playlists }); @@ -420,26 +423,49 @@ export default function reducer(ui = {}, action){ }) return Object.assign({}, ui, { search_results: results }) - case 'SPOTIFY_SEARCH_RESULTS_LOADED': - if( !action.data ) return ui + case 'SEARCH_RESULTS_LOADED': + if (action.reset) return ui - return Object.assign({}, ui, { search_results: { - artists: [ ...ui.search_results.artists, ...action.data.artists.items ], - albums: [ ...ui.search_results.albums, ...action.data.albums.items ], - playlists: [ ...ui.search_results.playlists, ...action.data.playlists.items ], - tracks: [ ...ui.search_results.tracks, ...action.data.tracks.items ], - artists_more: action.data.artists.next, - albums_more: action.data.albums.next, - playlists_more: action.data.playlists.next, - tracks_more: action.data.tracks.next - }}); + if (ui.search_results.artists_uris){ + var artists_uris = [...ui.search_results.artists_uris, ...action.artists_uris] + }else{ + var artists_uris = action.artists_uris + } + + if (ui.search_results.albums_uris){ + var albums_uris = [...ui.search_results.albums_uris, ...action.albums_uris] + }else{ + var albums_uris = action.albums_uris + } + + if (ui.search_results.playlists_uris){ + var playlists_uris = [...ui.search_results.playlists_uris, ...action.playlists_uris] + }else{ + var playlists_uris = action.playlists_uris + } + + return Object.assign({}, ui, { + search_results: { + artists_more: (action.artists_more ? action.artists_more : null), + artists_uris: artists_uris, + albums_more: (action.albums_more ? action.albums_more : null), + albums_uris: albums_uris, + playlists_more: (action.playlists_more ? action.playlists_more : null), + playlists_uris: playlists_uris, + tracks: [ ...ui.search_results.tracks, ...action.tracks.items ], + tracks_more: action.tracks.next + } + }); case 'SPOTIFY_SEARCH_RESULTS_LOADED_MORE_ARTISTS': - var artists = [...ui.search_results.artists, ...action.data.artists.items] - var results = Object.assign({}, ui.search_results, { - artists: artists, - artists_more: action.data.artists.next - }) + var results = Object.assign( + {}, + ui.search_results, + { + artists_uris: [...ui.search_results.artists_uris, ...action.data.artists_uris], + artists_more: action.data.artists.next + } + ) return Object.assign({}, ui, { search_results: results }) case 'SPOTIFY_SEARCH_RESULTS_LOADED_MORE_ALBUMS': diff --git a/src/js/views/Debug.js b/src/js/views/Debug.js index ee468bff..02fe0c46 100755 --- a/src/js/views/Debug.js +++ b/src/js/views/Debug.js @@ -76,6 +76,19 @@ class Debug extends React.Component{ +
+
Debug data
+
+ +
+

Mopidy

@@ -147,6 +160,7 @@ const mapStateToProps = (state, ownProps) => { return { connectionid: state.pusher.connectionid, emulate_touch: state.ui.emulate_touch, + log_actions: state.ui.log_actions, debug_response: state.ui.debug_response } } diff --git a/src/js/views/Search.js b/src/js/views/Search.js index 70db32fb..07681090 100755 --- a/src/js/views/Search.js +++ b/src/js/views/Search.js @@ -59,13 +59,44 @@ class Search extends React.Component{ } renderResults(){ + + var artists = [] + if (this.props.artists_uris){ + for (var i = 0; i < this.props.artists_uris.length; i++){ + var uri = this.props.artists_uris[i] + if (this.props.artists.hasOwnProperty(uri)){ + artists.push(this.props.artists[uri]) + } + } + } + + var albums = [] + if (this.props.albums_uris){ + for (var i = 0; i < this.props.albums_uris.length; i++){ + var uri = this.props.albums_uris[i] + if (this.props.albums.hasOwnProperty(uri)){ + albums.push(this.props.albums[uri]) + } + } + } + + var playlists = [] + if (this.props.playlists_uris){ + for (var i = 0; i < this.props.playlists_uris.length; i++){ + var uri = this.props.playlists_uris[i] + if (this.props.playlists.hasOwnProperty(uri)){ + playlists.push(this.props.playlists[uri]) + } + } + } + switch( this.props.params.type ){ case 'artists': return (
- + this.loadMore('artists') }/>
@@ -76,7 +107,7 @@ class Search extends React.Component{ return (
- + this.loadMore('albums') }/>
@@ -87,7 +118,7 @@ class Search extends React.Component{ return (
- + this.loadMore('playlists') }/>
@@ -98,7 +129,7 @@ class Search extends React.Component{ return (
- + this.loadMore('tracks') }/>
@@ -112,26 +143,26 @@ class Search extends React.Component{

Artists

- +

Albums

- +

Playlists

- +

Tracks

- + this.loadMore('tracks') }/>
@@ -154,7 +185,16 @@ const mapStateToProps = (state, ownProps) => { return { mopidy_connected: state.mopidy.connected, uri_schemes: state.mopidy.uri_schemes, - search_results: state.ui.search_results + tracks: (state.ui.search_results ? state.ui.search_results.tracks : []), + artists: state.ui.artists, + artists_uris: (state.ui.search_results ? state.ui.search_results.artists_uris : []), + artists_more: (state.ui.search_results ? state.ui.search_results.artists_more : null), + albums: state.ui.albums, + albums_uris: (state.ui.search_results ? state.ui.search_results.albums_uris : []), + albums_more: (state.ui.search_results ? state.ui.search_results.albums_more : null), + playlists: state.ui.playlists, + playlists_uris: (state.ui.search_results ? state.ui.search_results.playlists_uris : []), + playlists_more: (state.ui.search_results ? state.ui.search_results.playlists_more : null) } }