diff --git a/src/js/components/DropdownField.js b/src/js/components/DropdownField.js
index 74e42cbe..d2c7ff8c 100755
--- a/src/js/components/DropdownField.js
+++ b/src/js/components/DropdownField.js
@@ -60,7 +60,7 @@ export default class DropdownField extends React.Component{
return (
this.handleToggle() }>
- {this.props.icon ? : null}
+ {this.props.icon ? : null}
{ this.props.name }
diff --git a/src/js/components/Modal/Modal.js b/src/js/components/Modal/Modal.js
index ae0a04ab..751c4f1c 100755
--- a/src/js/components/Modal/Modal.js
+++ b/src/js/components/Modal/Modal.js
@@ -13,6 +13,7 @@ import SendAuthorizationModal from './SendAuthorizationModal'
import EditRadioModal from './EditRadioModal'
import ImageZoomModal from './ImageZoomModal'
import KioskModeModal from './KioskModeModal'
+import SearchSettingsModal from './SearchSettingsModal'
import * as uiActions from '../../services/ui/actions'
import * as mopidyActions from '../../services/mopidy/actions'
@@ -51,6 +52,7 @@ class Modal extends React.Component{
{ this.props.modal.name == 'edit_radio' ? : null }
{ this.props.modal.name == 'image_zoom' ? : null }
{ this.props.modal.name == 'kiosk_mode' ? : null }
+ { this.props.modal.name == 'search_settings' ? : null }
@@ -60,6 +62,8 @@ class Modal extends React.Component{
const mapStateToProps = (state, ownProps) => {
return {
+ uri_schemes: (state.mopidy.uri_schemes ? state.mopidy.uri_schemes : null),
+ search_settings: (state.ui.search_settings ? state.ui.search_settings : null),
modal: state.ui.modal,
radio: state.ui.radio,
tracks: state.ui.tracks,
diff --git a/src/js/components/Modal/SearchSettingsModal.js b/src/js/components/Modal/SearchSettingsModal.js
new file mode 100755
index 00000000..3f0c721c
--- /dev/null
+++ b/src/js/components/Modal/SearchSettingsModal.js
@@ -0,0 +1,90 @@
+
+import React, { PropTypes } from 'react'
+import FontAwesome from 'react-fontawesome'
+
+import Icon from '../Icon'
+import * as helpers from '../../helpers'
+
+export default class SearchSettingsModal extends React.Component{
+
+ constructor(props){
+ super(props)
+
+ this.state = {
+ spotify: true,
+ uri_schemes: []
+ }
+ }
+
+ componentDidMount(){
+ if (this.props.search_settings){
+ this.setState(this.props.search_settings)
+ } else {
+ this.setState({
+ spotify: true,
+ uri_schemes: this.props.uri_schemes
+ })
+ }
+ }
+
+ handleSubmit(e){
+ this.props.uiActions.set({search_settings: this.state})
+ this.props.uiActions.closeModal()
+ this.props.uiActions.startSearch(this.props.data.type, this.props.data.query)
+ }
+
+ handleToggle(scheme){
+ var uri_schemes = this.state.uri_schemes
+ var index = uri_schemes.indexOf(scheme)
+
+ if (index > -1){
+ uri_schemes.splice(index,1)
+ } else {
+ uri_schemes.push(scheme)
+ }
+
+ this.setState({uri_schemes: uri_schemes})
+ }
+
+ render(){
+ return (
+
+
Advanced search settings
+
Customise the providers used when searching
+
+
+
+ )
+ }
+}
\ No newline at end of file
diff --git a/src/js/components/SearchForm.js b/src/js/components/SearchForm.js
index 6bc1618e..5fb6fc08 100755
--- a/src/js/components/SearchForm.js
+++ b/src/js/components/SearchForm.js
@@ -7,7 +7,6 @@ import FontAwesome from 'react-fontawesome'
import * as helpers from '../helpers'
import * as uiActions from '../services/ui/actions'
-import * as spotifyActions from '../services/spotify/actions'
class SearchForm extends React.Component{
@@ -38,7 +37,7 @@ class SearchForm extends React.Component{
break
default:
- hashHistory.push(global.baseURL+'search/'+this.state.query)
+ hashHistory.push(global.baseURL+'search/all/'+this.state.query)
break
}
@@ -58,15 +57,10 @@ class SearchForm extends React.Component{
}
}
-const mapStateToProps = (state, ownProps) => {
- return state;
-}
-
const mapDispatchToProps = (dispatch) => {
return {
- uiActions: bindActionCreators(uiActions, dispatch),
- spotifyActions: bindActionCreators(spotifyActions, dispatch)
+ uiActions: bindActionCreators(uiActions, dispatch)
}
}
-export default connect(mapStateToProps, mapDispatchToProps)(SearchForm)
\ No newline at end of file
+export default connect(mapDispatchToProps)(SearchForm)
\ No newline at end of file
diff --git a/src/js/index.js b/src/js/index.js
index ca922a89..010cf572 100755
--- a/src/js/index.js
+++ b/src/js/index.js
@@ -60,8 +60,7 @@ ReactDOM.render(
-
-
+
diff --git a/src/js/services/ui/actions.js b/src/js/services/ui/actions.js
index d7aed541..20beda49 100755
--- a/src/js/services/ui/actions.js
+++ b/src/js/services/ui/actions.js
@@ -29,10 +29,12 @@ export function hideTouchContextMenu(){
}
}
-export function startSearch( query ){
+export function startSearch(search_type, query, only_mopidy = false){
return {
type: 'SEARCH_STARTED',
- query: query
+ search_type: search_type,
+ query: query,
+ only_mopidy: only_mopidy
}
}
diff --git a/src/js/services/ui/middleware.js b/src/js/services/ui/middleware.js
index 73a17cdc..9c0b1130 100755
--- a/src/js/services/ui/middleware.js
+++ b/src/js/services/ui/middleware.js
@@ -112,7 +112,26 @@ const UIMiddleware = (function(){
break
case 'SEARCH_STARTED':
- ReactGA.event({ category: 'Search', action: 'Started', label: action.query })
+ ReactGA.event({ category: 'Search', action: 'Started', label: action.type+': '+action.query })
+ var state = store.getState()
+
+ // initiate spotify searching
+ if (!action.only_mopidy){
+ if (!state.ui.search_settings || state.ui.search_settings.spotify){
+ store.dispatch(spotifyActions.getSearchResults(action.query))
+ }
+ }
+
+ // backend searching (mopidy)
+ if (state.mopidy.connected){
+ if (state.ui.search_settings){
+ var uri_schemes = state.ui.search_settings.uri_schemes
+ } else {
+ var uri_schemes = state.mopidy.uri_schemes
+ }
+ store.dispatch(mopidyActions.getSearchResults(action.query, uri_schemes))
+ }
+
next(action)
break
diff --git a/src/js/views/Search.js b/src/js/views/Search.js
index e36da71c..cb1b4a5c 100755
--- a/src/js/views/Search.js
+++ b/src/js/views/Search.js
@@ -26,34 +26,19 @@ class Search extends React.Component{
}
componentDidMount(){
- this.performSearch()
+ this.props.uiActions.startSearch(this.props.params.type, this.props.params.query)
}
componentWillReceiveProps(newProps){
// new query
if( this.props.params.query != newProps.params.query ){
- this.performSearch( newProps )
+ this.props.uiActions.startSearch(newProps.params.type, newProps.params.query)
}
// 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 ){
- var source = props.params.source
- var type = props.params.type
-
- this.props.uiActions.startSearch(props.params.query)
-
- if (!source || source == 'all' || source == 'spotify'){
- this.props.spotifyActions.getSearchResults( props.params.query )
- }
-
- if( props.mopidy_connected ){
- this.props.mopidyActions.getSearchResults( props.params.query, props.uri_schemes )
+ this.props.uiActions.startSearch(newProps.params.type, newProps.params.query, true)
}
}
@@ -62,14 +47,11 @@ class Search extends React.Component{
}
renderResults(){
- var type = (this.props.params.type ? this.props.params.type : 'all')
- var source = (this.props.params.source ? this.props.params.source : 'all')
-
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) && (source == 'all' || helpers.uriSource(uri) == source)){
+ if (this.props.artists.hasOwnProperty(uri)){
artists.push(this.props.artists[uri])
}
}
@@ -79,7 +61,7 @@ class Search extends React.Component{
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) && (source == 'all' || helpers.uriSource(uri) == source)){
+ if (this.props.albums.hasOwnProperty(uri)){
albums.push(this.props.albums[uri])
}
}
@@ -89,7 +71,7 @@ class Search extends React.Component{
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) && (source == 'all' || helpers.uriSource(uri) == source)){
+ if (this.props.playlists.hasOwnProperty(uri)){
playlists.push(this.props.playlists[uri])
}
}
@@ -97,25 +79,21 @@ class Search extends React.Component{
var tracks = []
if (this.props.tracks){
- if (source == 'all'){
- tracks = this.props.tracks
- } else {
- for (var i = 0; i < this.props.tracks.length; i++){
- if (helpers.uriSource(this.props.tracks[i].uri) == source){
- tracks.push(this.props.tracks[i])
- }
+ for (var i = 0; i < this.props.tracks.length; i++){
+ if (helpers.uriSource(this.props.tracks[i].uri)){
+ tracks.push(this.props.tracks[i])
}
}
}
- switch( type ){
+ switch (this.props.params.type){
case 'artists':
return (
- this.loadMore('artists') }/>
+ this.loadMore('artists') }/>
)
@@ -126,7 +104,7 @@ class Search extends React.Component{
- this.loadMore('albums') }/>
+ this.loadMore('albums') }/>
)
@@ -137,7 +115,7 @@ class Search extends React.Component{
- this.loadMore('playlists') }/>
+ this.loadMore('playlists') }/>
)
@@ -148,7 +126,7 @@ class Search extends React.Component{
- this.loadMore('tracks') }/>
+ this.loadMore('tracks') }/>
)
@@ -181,7 +159,7 @@ class Search extends React.Component{
Tracks
- this.loadMore('tracks') }/>
+ this.loadMore('tracks') }/>
@@ -191,14 +169,7 @@ class Search extends React.Component{
handleTypeChange(val){
this.props.uiActions.hideContextMenu()
- var source = (this.props.params.source ? this.props.params.source : 'all')
- hashHistory.push(global.baseURL+'search/'+this.props.params.query+'/'+source+'/'+val)
- }
-
- handleSourceChange(val){
- this.props.uiActions.hideContextMenu()
- var type = (this.props.params.type ? this.props.params.type : 'all')
- hashHistory.push(global.baseURL+'search/'+this.props.params.query+'/'+val+'/'+type)
+ hashHistory.push(global.baseURL+'search/'+val+'/'+this.props.params.query)
}
render(){
@@ -225,28 +196,13 @@ class Search extends React.Component{
}
]
- var source_options = [
- {
- value: 'all',
- label: 'All'
- },
- {
- value: 'spotify',
- label: 'Spotify'
- }
- ]
- for (var i = 0; i < this.props.uri_schemes.length; i++){
- var scheme = this.props.uri_schemes[i].replace(':','')
- source_options.push({
- value: scheme,
- label: scheme
- })
- }
-
var options = (
- this.handleTypeChange(val)} />
- this.handleSourceChange(val)} />
+ this.handleTypeChange(val)} />
+
)
@@ -262,7 +218,7 @@ class Search extends React.Component{
const mapStateToProps = (state, ownProps) => {
return {
mopidy_connected: state.mopidy.connected,
- uri_schemes: state.mopidy.uri_schemes,
+ search_settings: (state.ui.search_settings ? state.ui.search_settings : null),
tracks: (state.ui.search_results ? state.ui.search_results.tracks : []),
tracks_more: (state.ui.search_results && state.ui.search_results.tracks_more ? state.ui.search_results.tracks_more : null),
artists: state.ui.artists,
diff --git a/src/scss/global/_core.scss b/src/scss/global/_core.scss
index 897b088e..7c18b355 100755
--- a/src/scss/global/_core.scss
+++ b/src/scss/global/_core.scss
@@ -100,6 +100,10 @@ h3 {
font-weight: 100;
font-style: italic;
font-size: 20px;
+
+ &.bottom-padding {
+ padding-bottom: 30px;
+ }
}
h4 {