Search maturity; Service status
This commit is contained in:
@ -28,6 +28,7 @@ class App extends React.Component{
|
||||
componentWillMount(){
|
||||
this.props.pusherActions.connect();
|
||||
this.props.mopidyActions.connect();
|
||||
this.props.spotifyActions.connect();
|
||||
|
||||
window.addEventListener("keyup", this.handleKeyUp, false);
|
||||
window.addEventListener("keydown", this.handleKeyDown, false);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
|
||||
import React, { PropTypes } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { Link } from 'react-router'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import FontAwesome from 'react-fontawesome'
|
||||
|
||||
@ -9,6 +10,7 @@ import TrackList from '../components/TrackList'
|
||||
import ArtistGrid from '../components/ArtistGrid'
|
||||
import AlbumGrid from '../components/AlbumGrid'
|
||||
import PlaylistGrid from '../components/PlaylistGrid'
|
||||
import LazyLoadListener from '../components/LazyLoadListener'
|
||||
|
||||
import * as uiActions from '../services/ui/actions'
|
||||
import * as mopidyActions from '../services/mopidy/actions'
|
||||
@ -34,68 +36,122 @@ class Search extends React.Component{
|
||||
this.props.spotifyActions.getSearchResults( props.params.query )
|
||||
}
|
||||
|
||||
compiledTracks(){
|
||||
var tracks = [];
|
||||
if( this.props.mopidy.search_results ) tracks = [...tracks, ...this.props.mopidy.search_results.tracks]
|
||||
if( this.props.spotify.search_results ) tracks = [...tracks, ...this.props.spotify.search_results.tracks.items]
|
||||
return tracks;
|
||||
loadMore(type){
|
||||
if( !this.props.spotify['search_results_'+type] ||
|
||||
!this.props.spotify['search_results_'+type].next ){
|
||||
return
|
||||
}
|
||||
|
||||
this.props.spotifyActions.getURL(
|
||||
this.props.spotify['search_results_'+type].next,
|
||||
'SPOTIFY_SEARCH_RESULTS_LOADED_MORE_'+ type.toUpperCase()
|
||||
);
|
||||
}
|
||||
|
||||
compiledArtists(){
|
||||
var artists = [];
|
||||
if( this.props.mopidy.search_results ) artists = [...artists, ...this.props.mopidy.search_results.artists]
|
||||
if( this.props.spotify.search_results ) artists = [...artists, ...this.props.spotify.search_results.artists.items]
|
||||
return artists.splice(0,9)
|
||||
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;
|
||||
}
|
||||
|
||||
compiledAlbums(){
|
||||
var albums = [];
|
||||
if( this.props.mopidy.search_results ) tracks = [...albums, ...this.props.mopidy.search_results.albums]
|
||||
if( this.props.spotify.search_results ) albums = [...albums, ...this.props.spotify.search_results.albums.items]
|
||||
return albums.splice(0,9)
|
||||
}
|
||||
renderResults(){
|
||||
switch( this.props.params.type ){
|
||||
|
||||
compiledPlaylists(){
|
||||
var playlists = [];
|
||||
if( this.props.mopidy.search_results ) playlists = [...playlists, ...this.props.mopidy.search_results.playlists]
|
||||
if( this.props.spotify.search_results ) playlists = [...playlists, ...this.props.spotify.search_results.playlists.items]
|
||||
return playlists.splice(0,9)
|
||||
case 'artists':
|
||||
return (
|
||||
<div>
|
||||
<section className="grid-wrapper">
|
||||
<ArtistGrid artists={ this.compiledResults('artists') } />
|
||||
</section>
|
||||
<LazyLoadListener loadMore={ () => this.loadMore('artists') }/>
|
||||
</div>
|
||||
)
|
||||
break
|
||||
|
||||
case 'albums':
|
||||
return (
|
||||
<div>
|
||||
<section className="grid-wrapper">
|
||||
<AlbumGrid albums={ this.compiledResults('albums') } />
|
||||
</section>
|
||||
<LazyLoadListener loadMore={ () => this.loadMore('albums') }/>
|
||||
</div>
|
||||
)
|
||||
break
|
||||
|
||||
case 'playlists':
|
||||
return (
|
||||
<div>
|
||||
<section className="grid-wrapper">
|
||||
<PlaylistGrid playlists={ this.compiledResults('playlists') } />
|
||||
</section>
|
||||
<LazyLoadListener loadMore={ () => this.loadMore('playlists') }/>
|
||||
</div>
|
||||
)
|
||||
break
|
||||
|
||||
case 'tracks':
|
||||
return (
|
||||
<div>
|
||||
<section className="list-wrapper">
|
||||
<TrackList tracks={ this.compiledResults('tracks') } />
|
||||
</section>
|
||||
<LazyLoadListener loadMore={ () => this.loadMore('tracks') }/>
|
||||
</div>
|
||||
)
|
||||
break
|
||||
|
||||
default:
|
||||
return (
|
||||
<div>
|
||||
<div className="search-result-sections cf">
|
||||
<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) } />
|
||||
</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) } />
|
||||
</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) } />
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section className="list-wrapper">
|
||||
<h4><Link to={'/search/'+this.props.params.query+'/tracks'}>Tracks</Link></h4>
|
||||
<TrackList tracks={ this.compiledResults('tracks') } />
|
||||
</section>
|
||||
|
||||
<LazyLoadListener loadMore={ () => this.loadMore('tracks') }/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
return (
|
||||
<div className="view search-view">
|
||||
|
||||
<Header
|
||||
icon="search"
|
||||
title="Search results"
|
||||
/>
|
||||
|
||||
<div className="search-result-sections cf">
|
||||
<section>
|
||||
<div className="inner">
|
||||
<h4>Artists</h4>
|
||||
<ArtistGrid className="mini" artists={ this.compiledArtists() } />
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<div className="inner">
|
||||
<h4 >Albums</h4>
|
||||
<AlbumGrid className="mini" albums={ this.compiledAlbums() } />
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<div className="inner">
|
||||
<h4>Playlists</h4>
|
||||
<PlaylistGrid className="mini" playlists={ this.compiledPlaylists() } />
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section className="list-wrapper">
|
||||
<TrackList tracks={ this.compiledTracks() } />
|
||||
</section>
|
||||
|
||||
<div className="view search-view">
|
||||
<Header icon="search" title="Search results" />
|
||||
{ this.renderResults() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -55,6 +55,34 @@ class Settings extends React.Component{
|
||||
}
|
||||
}
|
||||
|
||||
renderConnectionStatus(service){
|
||||
if( this.props[service].connected ){
|
||||
return (
|
||||
<span className="text green-text connection-status">
|
||||
<FontAwesome name="check" />
|
||||
|
||||
Connected
|
||||
</span>
|
||||
)
|
||||
}else if( this.props[service].connecting ){
|
||||
return (
|
||||
<span className="text grey-text connection-status">
|
||||
<FontAwesome name="circle-o-notch" spin />
|
||||
|
||||
Connecting
|
||||
</span>
|
||||
)
|
||||
}else{
|
||||
return (
|
||||
<span className="text red-text connection-status">
|
||||
<FontAwesome name="exclamation-triangle" />
|
||||
|
||||
Not connected
|
||||
</span>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
return (
|
||||
<div className="view settings-view">
|
||||
@ -67,22 +95,28 @@ class Settings extends React.Component{
|
||||
|
||||
<h4 className="underline">Mopidy</h4>
|
||||
<form onSubmit={(e) => this.setMopidyConfig(e)}>
|
||||
<label>
|
||||
<div className="label">Status</div>
|
||||
<div className="input">
|
||||
{ this.renderConnectionStatus('mopidy') }
|
||||
</div>
|
||||
</label>
|
||||
<label>
|
||||
<div className="label">Host</div>
|
||||
<div className="input">
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ mopidy_host: e.target.value })}
|
||||
value={ this.state.mopidy_host } />
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ mopidy_host: e.target.value })}
|
||||
value={ this.state.mopidy_host } />
|
||||
</div>
|
||||
</label>
|
||||
<label>
|
||||
<div className="label">Port</div>
|
||||
<div className="input">
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ mopidy_port: e.target.value })}
|
||||
value={ this.state.mopidy_port } />
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ mopidy_port: e.target.value })}
|
||||
value={ this.state.mopidy_port } />
|
||||
</div>
|
||||
</label>
|
||||
<button type="submit" className="secondary">Apply</button>
|
||||
@ -90,38 +124,50 @@ class Settings extends React.Component{
|
||||
|
||||
<h4 className="underline">Pusher</h4>
|
||||
<form>
|
||||
<label>
|
||||
<div className="label">Status</div>
|
||||
<div className="input">
|
||||
{ this.renderConnectionStatus('pusher') }
|
||||
</div>
|
||||
</label>
|
||||
<label>
|
||||
<div className="label">Username</div>
|
||||
<div className="input">
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ pusher_username: e.target.value }) }
|
||||
onBlur={ e => this.props.pusherActions.changeUsername( this.state.pusher_username ) }
|
||||
value={ this.state.pusher_username } />
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ pusher_username: e.target.value }) }
|
||||
onBlur={ e => this.props.pusherActions.changeUsername( this.state.pusher_username ) }
|
||||
value={ this.state.pusher_username } />
|
||||
</div>
|
||||
</label>
|
||||
<label>
|
||||
<div className="label">Port</div>
|
||||
<div className="input">
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ pusher_port: e.target.value })}
|
||||
onBlur={ e => this.props.pusherActions.setPort({ port: this.state.pusher_port }) }
|
||||
value={ this.state.pusher_port } />
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ pusher_port: e.target.value })}
|
||||
onBlur={ e => this.props.pusherActions.setPort({ port: this.state.pusher_port }) }
|
||||
value={ this.state.pusher_port } />
|
||||
</div>
|
||||
</label>
|
||||
</form>
|
||||
|
||||
<h4 className="underline">Spotify</h4>
|
||||
<form onSubmit={(e) => this.setSpotifyConfig(e)}>
|
||||
<label>
|
||||
<div className="label">Status</div>
|
||||
<div className="input">
|
||||
{ this.renderConnectionStatus('spotify') }
|
||||
</div>
|
||||
</label>
|
||||
<label>
|
||||
<div className="label">Country</div>
|
||||
<div className="input">
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ spotify_country: e.target.value })}
|
||||
onBlur={ e => this.setSpotifyConfig(e) }
|
||||
value={ this.state.spotify_country } />
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ spotify_country: e.target.value })}
|
||||
onBlur={ e => this.setSpotifyConfig(e) }
|
||||
value={ this.state.spotify_country } />
|
||||
</div>
|
||||
</label>
|
||||
<label>
|
||||
@ -141,13 +187,13 @@ class Settings extends React.Component{
|
||||
<h4 className="underline">Advanced</h4>
|
||||
<label>
|
||||
<div className="label">Version</div>
|
||||
<div className="input">
|
||||
<div className="input read-only">
|
||||
<VersionManager />
|
||||
</div>
|
||||
</label>
|
||||
<label>
|
||||
<div className="label">Connections</div>
|
||||
<div className="input">
|
||||
<div className="input read-only">
|
||||
<PusherConnectionList />
|
||||
</div>
|
||||
</label>
|
||||
|
||||
Reference in New Issue
Block a user