Moving search into UI

This commit is contained in:
James Barnsley
2016-11-09 15:49:25 +13:00
parent 88caab6aef
commit b0109abd44
10 changed files with 730 additions and 670 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

8
src/js/bootstrap.js vendored
View File

@ -57,7 +57,13 @@ var initialState = {
show: false
},
current_tracklist: [],
current_tltrack: false
current_tltrack: false,
search_results: {
artists: [],
albums: [],
playlists: [],
tracks: []
}
}
};

View File

@ -79,6 +79,8 @@ const MopidyMiddleware = (function(){
**/
const instruct = ( ws, store, call, value = {} ) => {
if( !store.getState().mopidy.connected ) return false
var callParts = call.split('.');
var model = callParts[0];
var method = callParts[1];

View File

@ -96,15 +96,6 @@ export default function reducer(mopidy = {}, action){
albums: action.data
});
case 'MOPIDY_SEARCH':
var results = []
for( var i = 0; i < action.data.length; i++ ){
if( action.data[i].tracks ) results = [...results, ...action.data[i].tracks]
}
return Object.assign({}, mopidy, {
search_results_tracks: results
});
default:
return mopidy
}

View File

@ -144,46 +144,6 @@ export default function reducer(spotify = {}, action){
items: [ ...spotify.new_releases.items, ...action.data.albums.items ]
}});
case 'SPOTIFY_SEARCH_RESULTS_LOADED':
return Object.assign({}, spotify, {
search_results_artists: action.data.artists,
search_results_albums: action.data.albums,
search_results_playlists: action.data.playlists,
search_results_tracks: action.data.tracks
});
case 'SPOTIFY_SEARCH_RESULTS_LOADED_MORE_ARTISTS':
return Object.assign({}, spotify, { search_results_artists: {
href: action.data.artists.href,
next: action.data.artists.next,
previous: action.data.artists.previous,
items: [ ...spotify.search_results_artists.items, ...action.data.artists.items ]
}});
case 'SPOTIFY_SEARCH_RESULTS_LOADED_MORE_ALBUMS':
return Object.assign({}, spotify, { search_results_albums: {
href: action.data.albums.href,
next: action.data.albums.next,
previous: action.data.albums.previous,
items: [ ...spotify.search_results_albums.items, ...action.data.albums.items ]
}});
case 'SPOTIFY_SEARCH_RESULTS_LOADED_MORE_PLAYLISTS':
return Object.assign({}, spotify, { search_results_playlists: {
href: action.data.playlists.href,
next: action.data.playlists.next,
previous: action.data.playlists.previous,
items: [ ...spotify.search_results_playlists.items, ...action.data.playlists.items ]
}});
case 'SPOTIFY_SEARCH_RESULTS_LOADED_MORE_TRACKS':
return Object.assign({}, spotify, { search_results_tracks: {
href: action.data.tracks.href,
next: action.data.tracks.next,
previous: action.data.tracks.previous,
items: [ ...spotify.search_results_tracks.items, ...action.data.tracks.items ]
}});
default:
return spotify
}

View File

@ -11,8 +11,24 @@ export function showContextMenu( e, context = false, data ){
}
export function hideContextMenu(){
return {
type: 'UI_HIDE_CONTEXT_MENU'
}
}
export function searchStarted(){
return {
type: 'UI_HIDE_CONTEXT_MENU'
type: 'SEARCH_STARTED',
data: {
artists: [],
albums: [],
playlists: [],
tracks: [],
artists_more: false,
albums_more: false,
playlists_more: false,
tracks_more: false
}
}
}

View File

@ -78,6 +78,74 @@ export default function reducer(ui = {}, action){
current_track: current_track
});
/**
* Search results
**/
case 'SEARCH_STARTED':
return Object.assign({}, ui, { search_results: action.data })
case 'MOPIDY_SEARCH':
// collate all our different sources into one array
var tracks = []
for( var i = 0; i < action.data.length; i++ ){
if( action.data[i].tracks ) tracks = [...tracks, ...action.data[i].tracks]
}
// merge our results with all our other tracks
var results = Object.assign({}, ui.search_results, {
tracks: [...ui.search_results.tracks, ...tracks]
})
return Object.assign({}, ui, { search_results: results })
case 'SPOTIFY_SEARCH_RESULTS_LOADED':
if( !action.data ) 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
}});
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
})
return Object.assign({}, ui, { search_results: results })
case 'SPOTIFY_SEARCH_RESULTS_LOADED_MORE_ALBUMS':
var albums = [...ui.search_results.albums, ...action.data.albums.items]
var results = Object.assign({}, ui.search_results, {
albums: albums,
albums_more: action.data.albums.next
})
return Object.assign({}, ui, { search_results: results })
case 'SPOTIFY_SEARCH_RESULTS_LOADED_MORE_PLAYLISTS':
var playlists = [...ui.search_results.playlists, ...action.data.playlists.items]
var results = Object.assign({}, ui.search_results, {
playlists: playlists,
playlists_more: action.data.playlists.next
})
return Object.assign({}, ui, { search_results: results })
case 'SPOTIFY_SEARCH_RESULTS_LOADED_MORE_TRACKS':
var tracks = [...ui.search_results.tracks, ...action.data.tracks.items]
var results = Object.assign({}, ui.search_results, {
tracks: tracks,
tracks_more: action.data.tracks.next
})
return Object.assign({}, ui, { search_results: results })
default:
return ui
}

View File

@ -27,48 +27,36 @@ class Search extends React.Component{
}
componentWillReceiveProps(newProps){
if( this.props.params.query != newProps.params.query ||
!this.props.mopidy.connected && newProps.mopidy.connected ){
this.performSearch( newProps )
// new query
if( this.props.params.query != newProps.params.query ){
this.performSearch( newProps )
}
// mopidy comes online
if( !this.props.mopidy_connected && newProps.mopidy_connected ){
this.props.mopidyActions.getSearchResults( newProps.params.query, newProps.uri_schemes )
}
}
performSearch( props = this.props ){
this.props.uiActions.searchStarted()
this.props.spotifyActions.getSearchResults( props.params.query )
if( props.mopidy.connected ){
this.props.mopidyActions.getSearchResults( props.params.query, props.mopidy.uri_schemes )
}
this.props.mopidyActions.getSearchResults( props.params.query, props.uri_schemes )
}
loadMore(type){
if( !this.props.spotify['search_results_'+type] ||
!this.props.spotify['search_results_'+type].next ){
if( !this.props.search_results[type] ||
!this.props.search_results[type+'_more'] ){
return
}
this.props.spotifyActions.getURL(
this.props.spotify['search_results_'+type].next,
this.props.search_results[type+'_more'],
'SPOTIFY_SEARCH_RESULTS_LOADED_MORE_'+ type.toUpperCase()
);
}
compiledResults(type){
var results = [];
// merge our mopidy results in
if( this.props.mopidy['search_results_'+type] ){
results = [...results, ...this.props.mopidy['search_results_'+type]]
}
// merge our spotify results in
if( this.props.spotify['search_results_'+type] &&
this.props.spotify['search_results_'+type].items ){
results = [...results, ...this.props.spotify['search_results_'+type].items]
}
return results;
}
renderResults(){
switch( this.props.params.type ){
@ -76,7 +64,7 @@ class Search extends React.Component{
return (
<div>
<section className="grid-wrapper">
<ArtistGrid artists={ this.compiledResults('artists') } />
<ArtistGrid artists={ this.props.search_results.artists } />
<LazyLoadListener loadMore={ () => this.loadMore('artists') }/>
</section>
</div>
@ -87,7 +75,7 @@ class Search extends React.Component{
return (
<div>
<section className="grid-wrapper">
<AlbumGrid albums={ this.compiledResults('albums') } />
<AlbumGrid albums={ this.props.search_results.albums } />
<LazyLoadListener loadMore={ () => this.loadMore('albums') }/>
</section>
</div>
@ -98,7 +86,7 @@ class Search extends React.Component{
return (
<div>
<section className="grid-wrapper">
<PlaylistGrid playlists={ this.compiledResults('playlists') } />
<PlaylistGrid playlists={ this.props.search_results.playlists } />
<LazyLoadListener loadMore={ () => this.loadMore('playlists') }/>
</section>
</div>
@ -109,7 +97,7 @@ class Search extends React.Component{
return (
<div>
<section className="list-wrapper">
<TrackList show_source_icon={true} tracks={ this.compiledResults('tracks') } />
<TrackList show_source_icon={true} tracks={ this.props.search_results.tracks } />
<LazyLoadListener loadMore={ () => this.loadMore('tracks') }/>
</section>
</div>
@ -123,26 +111,26 @@ class Search extends React.Component{
<section>
<div className="inner">
<h4><Link to={'/search/'+this.props.params.query+'/artists'}>Artists</Link></h4>
<ArtistGrid className="mini" artists={ this.compiledResults('artists').splice(0,6) } />
<ArtistGrid className="mini" artists={ this.props.search_results.artists.slice(0,6) } />
</div>
</section>
<section>
<div className="inner">
<h4><Link to={'/search/'+this.props.params.query+'/albums'}>Albums</Link></h4>
<AlbumGrid className="mini" albums={ this.compiledResults('albums').splice(0,6) } />
<AlbumGrid className="mini" albums={ this.props.search_results.albums.slice(0,6) } />
</div>
</section>
<section>
<div className="inner">
<h4><Link to={'/search/'+this.props.params.query+'/playlists'}>Playlists</Link></h4>
<PlaylistGrid className="mini" playlists={ this.compiledResults('playlists').splice(0,6) } />
<PlaylistGrid className="mini" playlists={ this.props.search_results.playlists.slice(0,6) } />
</div>
</section>
</div>
<section className="list-wrapper">
<h4 className="left-padding"><Link to={'/search/'+this.props.params.query+'/tracks'}>Tracks</Link></h4>
<TrackList show_source_icon={true} tracks={ this.compiledResults('tracks') } />
<TrackList show_source_icon={true} tracks={ this.props.search_results.tracks } />
<LazyLoadListener loadMore={ () => this.loadMore('tracks') }/>
</section>
@ -162,7 +150,11 @@ class Search extends React.Component{
}
const mapStateToProps = (state, ownProps) => {
return state;
return {
mopidy_connected: state.mopidy.connected,
uri_schemes: state.mopidy.uri_schemes,
search_results: state.ui.search_results
}
}
const mapDispatchToProps = (dispatch) => {

View File

@ -87,10 +87,7 @@ class Settings extends React.Component{
render(){
return (
<div className="view settings-view">
<Header
icon="cog"
title="Settings"
/>
<Header icon="cog" title="Settings" />
<section>