diff --git a/src/js/components/FilterField.js b/src/js/components/FilterField.js
new file mode 100755
index 00000000..e9e203e1
--- /dev/null
+++ b/src/js/components/FilterField.js
@@ -0,0 +1,74 @@
+
+import React, { PropTypes } from 'react'
+import { Link } from 'react-router'
+import FontAwesome from 'react-fontawesome'
+
+export default class FilterField extends React.Component{
+
+ constructor(props) {
+ super(props)
+ this.state = {
+ value: '',
+ active: false
+ }
+
+ this.handleKeyUp = this.handleKeyUp.bind(this)
+ }
+
+ componentWillMount(){
+ window.addEventListener("keyup", this.handleKeyUp, false)
+ }
+
+ componentWillUnmount(){
+ window.removeEventListener("keyup", this.handleKeyUp, false)
+ }
+
+ handleKeyUp(e){
+ if (e.keyCode == 27){
+ e.preventDefault()
+
+ this.setState({
+ value: '',
+ active: false
+ })
+
+ this.handleChange('')
+ }
+ }
+
+ activate(){
+ this.setState({active: true})
+ }
+
+ handleChange(value){
+ this.setState({
+ value: value,
+ active: (value != '')
+ })
+ this.props.handleChange(value)
+ }
+
+ handleBlur(){
+ if (this.state.value == ''){
+ this.setState({active: false})
+ }
+ }
+
+ render(){
+ return (
+ this.activate()}>
+
+
+ )
+ }
+}
\ No newline at end of file
diff --git a/src/js/helpers.js b/src/js/helpers.js
index 5977ce85..d6a885ef 100755
--- a/src/js/helpers.js
+++ b/src/js/helpers.js
@@ -380,6 +380,27 @@ export let removeDuplicates = function(array){
}
+/**
+ * Apply a partial text search on an array of objects
+ *
+ * @param field = string (the field we're to search)
+ * @param value = string (the value to find)
+ * @param array = array of objects to search
+ * @return array
+ **/
+export let applyFilter = function(field, value, array){
+ var results = []
+
+ for (var i = 0; i < array.length; i++){
+ if (array[i][field] && array[i][field].toLowerCase().includes(value.toLowerCase())){
+ results.push(array[i])
+ }
+ }
+
+ return results
+}
+
+
/**
* 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/views/library/LibraryAlbums.js b/src/js/views/library/LibraryAlbums.js
index 3900d9db..66ec7bfb 100755
--- a/src/js/views/library/LibraryAlbums.js
+++ b/src/js/views/library/LibraryAlbums.js
@@ -11,7 +11,7 @@ import Thumbnail from '../../components/Thumbnail'
import TrackList from '../../components/TrackList'
import ArtistSentence from '../../components/ArtistSentence'
import DropdownField from '../../components/DropdownField'
-import LazyLoadListener from '../../components/LazyLoadListener'
+import FilterField from '../../components/FilterField'
import * as helpers from '../../helpers'
import * as coreActions from '../../services/core/actions'
@@ -23,20 +23,24 @@ class LibraryAlbums extends React.Component{
constructor(props) {
super(props)
+
+ this.state = {
+ filter: ''
+ }
}
componentDidMount(){
- if (!this.props.mopidy_library_albums && this.props.mopidy_connected && (this.props.filter == 'all' || this.props.filter == 'local')){
+ if (!this.props.mopidy_library_albums && this.props.mopidy_connected && (this.props.source == 'all' || this.props.source == 'local')){
this.props.mopidyActions.getLibraryAlbums()
}
- if (!this.props.spotify_library_albums && this.props.spotify_connected && (this.props.filter == 'all' || this.props.filter == 'spotify')){
+ if (!this.props.spotify_library_albums && this.props.spotify_connected && (this.props.source == 'all' || this.props.source == 'spotify')){
this.props.spotifyActions.getLibraryAlbums()
}
}
componentWillReceiveProps(newProps){
- if (newProps.mopidy_connected && (newProps.filter == 'all' || newProps.filter == 'local')){
+ if (newProps.mopidy_connected && (newProps.source == 'all' || newProps.source == 'local')){
// We've just connected
if (!this.props.mopidy_connected){
@@ -44,12 +48,12 @@ class LibraryAlbums extends React.Component{
}
// 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){
+ if (this.props.source != 'all' && this.props.source != 'local' && !newProps.mopidy_library_albums){
this.props.mopidyActions.getLibraryAlbums()
}
}
- if (newProps.spotify_connected && (newProps.filter == 'all' || newProps.filter == 'spotify')){
+ if (newProps.spotify_connected && (newProps.source == 'all' || newProps.source == 'spotify')){
// We've just connected
if (!this.props.spotify_connected){
@@ -57,7 +61,7 @@ class LibraryAlbums extends React.Component{
}
// 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){
+ if (this.props.source != 'all' && this.props.source != 'spotify' && !newProps.spotify_library_albums){
this.props.spotifyActions.getLibraryAlbums()
}
}
@@ -182,7 +186,7 @@ class LibraryAlbums extends React.Component{
var albums = []
// Spotify library items
- if (this.props.spotify_library_albums && (this.props.filter == 'all' || this.props.filter == 'spotify')){
+ if (this.props.spotify_library_albums && (this.props.source == 'all' || this.props.source == '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)){
@@ -192,7 +196,7 @@ class LibraryAlbums extends React.Component{
}
// Mopidy library items
- if (this.props.mopidy_library_albums && (this.props.filter == 'all' || this.props.filter == 'local')){
+ if (this.props.mopidy_library_albums && (this.props.source == 'all' || this.props.source == 'local')){
for (var i = 0; i < this.props.mopidy_library_albums.length; i++){
// Construct item placeholder. This is used as Mopidy needs to
@@ -214,7 +218,11 @@ class LibraryAlbums extends React.Component{
albums = helpers.sortItems(albums, this.props.sort, this.props.sort_reverse)
- var filter_options = [
+ if (this.state.filter && this.state.filter !== ''){
+ albums = helpers.applyFilter('name', this.state.filter, albums)
+ }
+
+ var source_options = [
{
value: 'all',
label: 'All'
@@ -265,9 +273,10 @@ class LibraryAlbums extends React.Component{
var options = (
- {this.props.uiActions.set({ library_albums_filter: val}); this.props.uiActions.hideContextMenu() }} />
+ this.setState({filter: value})} />
{this.setSort(val); this.props.uiActions.hideContextMenu() }} />
{this.props.uiActions.set({ library_albums_view: val }); this.props.uiActions.hideContextMenu() }} />
+ {this.props.uiActions.set({ library_albums_source: val}); this.props.uiActions.hideContextMenu() }} />
)
@@ -301,7 +310,7 @@ const mapStateToProps = (state, ownProps) => {
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'),
+ source: (state.ui.library_albums_source ? state.ui.library_albums_source : 'all'),
sort: (state.ui.library_albums_sort ? state.ui.library_albums_sort : 'name'),
sort_reverse: (state.ui.library_albums_sort_reverse ? true : false)
}
diff --git a/src/js/views/library/LibraryArtists.js b/src/js/views/library/LibraryArtists.js
index 3282be65..3c73d5e9 100755
--- a/src/js/views/library/LibraryArtists.js
+++ b/src/js/views/library/LibraryArtists.js
@@ -9,6 +9,7 @@ import Header from '../../components/Header'
import ArtistGrid from '../../components/ArtistGrid'
import List from '../../components/List'
import DropdownField from '../../components/DropdownField'
+import FilterField from '../../components/FilterField'
import * as helpers from '../../helpers'
import * as uiActions from '../../services/ui/actions'
@@ -18,21 +19,25 @@ import * as spotifyActions from '../../services/spotify/actions'
class LibraryArtists extends React.Component{
constructor(props) {
- super(props);
+ super(props)
+
+ this.state = {
+ filter: ''
+ }
}
componentDidMount(){
- if (!this.props.mopidy_library_artists && this.props.mopidy_connected && (this.props.filter == 'all' || this.props.filter == 'local')){
- this.props.mopidyActions.getLibraryartists()
+ if (!this.props.mopidy_library_artists && this.props.mopidy_connected && (this.props.source == 'all' || this.props.source == 'local')){
+ this.props.mopidyActions.getLibraryArtists()
}
- if (!this.props.spotify_library_artists && this.props.spotify_connected && (this.props.filter == 'all' || this.props.filter == 'spotify')){
- this.props.spotifyActions.getLibraryartists()
+ if (!this.props.spotify_library_artists && this.props.spotify_connected && (this.props.source == 'all' || this.props.source == 'spotify')){
+ this.props.spotifyActions.getLibraryArtists()
}
}
componentWillReceiveProps(newProps){
- if (newProps.mopidy_connected && (newProps.filter == 'all' || newProps.filter == 'local')){
+ if (newProps.mopidy_connected && (newProps.source == 'all' || newProps.source == 'local')){
// We've just connected
if (!this.props.mopidy_connected){
@@ -40,12 +45,12 @@ class LibraryArtists extends React.Component{
}
// Filter changed, but we haven't got this provider's library yet
- if (this.props.filter != 'all' && this.props.filter != 'local' && !newProps.mopidy_library_artists){
+ if (this.props.source != 'all' && this.props.source != 'local' && !newProps.mopidy_library_artists){
this.props.mopidyActions.getLibraryArtists()
}
}
- if (newProps.spotify_connected && (newProps.filter == 'all' || newProps.filter == 'spotify')){
+ if (newProps.spotify_connected && (newProps.source == 'all' || newProps.source == 'spotify')){
// We've just connected
if (!this.props.spotify_connected){
@@ -53,7 +58,7 @@ class LibraryArtists extends React.Component{
}
// Filter changed, but we haven't got this provider's library yet
- if (this.props.filter != 'all' && this.props.filter != 'spotify' && !newProps.spotify_library_artists){
+ if (this.props.source != 'all' && this.props.source != 'spotify' && !newProps.spotify_library_artists){
this.props.spotifyActions.getLibraryArtists()
}
}
@@ -121,7 +126,7 @@ class LibraryArtists extends React.Component{
var artists = []
// Mopidy library items
- if (this.props.mopidy_library_artists && (this.props.filter == 'all' || this.props.filter == 'local')){
+ if (this.props.mopidy_library_artists && (this.props.source == 'all' || this.props.source == 'local')){
for (var i = 0; i < this.props.mopidy_library_artists.length; i++){
// Construct item placeholder. This is used as Mopidy needs to
@@ -142,7 +147,7 @@ class LibraryArtists extends React.Component{
}
// Spotify library items
- if (this.props.spotify_library_artists){
+ if (this.props.spotify_library_artists && (this.props.source == 'all' || this.props.source == 'spotify')){
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)){
@@ -153,7 +158,11 @@ class LibraryArtists extends React.Component{
artists = helpers.sortItems(artists, this.props.sort, this.props.sort_reverse)
- var filter_options = [
+ if (this.state.filter !== ''){
+ artists = helpers.applyFilter('name', this.state.filter, artists)
+ }
+
+ var source_options = [
{
value: 'all',
label: 'All'
@@ -196,9 +205,10 @@ class LibraryArtists extends React.Component{
var options = (
- {this.props.uiActions.set({ library_artists_filter: val}); this.props.uiActions.hideContextMenu() }} />
+ this.setState({filter: value})} />
{this.setSort(value); this.props.uiActions.hideContextMenu() }} />
{this.props.uiActions.set({ library_artists_view: value }); this.props.uiActions.hideContextMenu()}} />
+ {this.props.uiActions.set({ library_artists_source: val}); this.props.uiActions.hideContextMenu() }} />
)
@@ -225,10 +235,10 @@ const mapStateToProps = (state, ownProps) => {
mopidy_library_artists: state.mopidy.library_artists,
spotify_library_artists: state.spotify.library_artists,
artists: state.core.artists,
- filter: (state.ui.library_artists_filter ? state.ui.library_artists_filter : 'all'),
+ source: (state.ui.library_artists_source ? state.ui.library_artists_source : 'all'),
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
+ view: state.ui.library_artists_view
}
}
diff --git a/src/js/views/library/LibraryBrowse.js b/src/js/views/library/LibraryBrowse.js
index 85ce98cb..e7720050 100755
--- a/src/js/views/library/LibraryBrowse.js
+++ b/src/js/views/library/LibraryBrowse.js
@@ -105,7 +105,7 @@ class LibraryBrowse extends React.Component{
var options = null
if (this.props.params.uri != 'local:directory' ){
options = (
-