diff --git a/app/api/Lastfm.js b/app/api/Lastfm.js index 76fe92afde..6537c558f2 100644 --- a/app/api/Lastfm.js +++ b/app/api/Lastfm.js @@ -86,13 +86,19 @@ function getTrackInfo(artist, track, callback) { }); } -function artistSearch(artist, callback) { - Axios.get(addApiKey( +function artistSearch(artist, callback, limit) { + var url = addApiKey( scrobblingApiUrl + '?method=artist.search&artist=' + encodeURIComponent(artist) + '&format=json' - )) + ); + + if (limit !== undefined) { + url += '&limit=' + limit; + } + + Axios.get(url) .then((response) => { callback(response); }); @@ -134,13 +140,19 @@ function getArtistTopAlbums(artist, callback) { }); } -function albumSearch(album, callback) { - Axios.get(addApiKey( +function albumSearch(album, callback, limit) { + var url = addApiKey( scrobblingApiUrl + '?method=album.search&album=' + encodeURIComponent(album) + '&format=json' - )) + ); + + if (limit !== undefined) { + url += '&limit=' + limit; + } + + Axios.get(url) .then((response) => { callback(response); }); @@ -169,6 +181,24 @@ function getTopTracks(callback) { }); } +function trackSearch(track, callback, limit) { + var url = addApiKey( + scrobblingApiUrl + + '?method=track.search&track=' + + encodeURIComponent(track) + + '&format=json' + ); + + if (limit !== undefined) { + url += '&limit=' + limit; + } + + Axios.get(url) + .then((response) => { + callback(response); + }); +} + module.exports = { lastfmLoginConnect: lastfmLoginConnect, lastfmLogin: lastfmLogin, @@ -177,6 +207,7 @@ module.exports = { getAlbumInfo: getAlbumInfo, albumSearch: albumSearch, artistSearch: artistSearch, + trackSearch: trackSearch, getArtistInfo: getArtistInfo, getArtistTopTracks: getArtistTopTracks, getArtistTopAlbums: getArtistTopAlbums, diff --git a/app/components/SearchSidebar.css b/app/components/SearchSidebar.css index 2d1c9e8b2b..67d7450d2f 100644 --- a/app/components/SearchSidebar.css +++ b/app/components/SearchSidebar.css @@ -18,9 +18,82 @@ } .search_sidebar { - position: relative; + position: absolute; width: 300px; height: 100%; + background-color: #1e1e26; + overflow-y: scroll; +} + +.search_sidebar>h3 { + margin: 20px 0px 10px 20px; + font-size: 20px; +} + +.search_sidebar_artist_container { + font-size: 14px; + font-weight: normal; background-color: #2a2a35; - overflow: scroll; + padding: 4px; + margin: 12px; +} + +.search_sidebar_artist_name { + margin: 16px; +} + +.search_sidebar_track_container { + font-size: 14px; + font-weight: normal; + background-color: #2a2a35; + padding: 4px; + margin: 12px; + display: flex; + flex-flow: row; + white-space: nowrap; + overflow: hidden; +} + +.search_sidebar_track_info { + margin: auto 16px auto 16px; + width: 0px; + flex: 1 1 auto; +} + +.search_sidebar_track_name { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.search_sidebar_track_artist { + color: #95a5a6; +} + +.search_sidebar_album_container { + font-size: 14px; + font-weight: normal; + background-color: #2a2a35; + padding: 4px; + margin: 12px; + display: flex; + flex-flow: row; + white-space: nowrap; + overflow: hidden; +} + +.search_sidebar_album_info { + margin: auto 16px auto 16px; + width: 0px; + flex: 1 1 auto; +} + +.search_sidebar_album_name { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.search_sidebar_album_artist { + color: #95a5a6; } diff --git a/app/components/SearchSidebar.js b/app/components/SearchSidebar.js index b538ec3da5..32602986ad 100644 --- a/app/components/SearchSidebar.js +++ b/app/components/SearchSidebar.js @@ -8,12 +8,57 @@ export default class SearchSidebar extends Component { } render() { - return ( -
-
+ if (this.props.searchResults === null) { + return null; + } else { + console.log(this.props.searchResults); + + return ( +
+
+

Artists

+ { + this.props.searchResults.artists.artist.map((el, i) => { + return ( +
+ + {el.name} +
+ ); + }) + } +

Songs

+ { + this.props.searchResults.tracks.track.map((el, i) => { + return ( +
+ +
+
{el.name}
+
by {el.artist}
+
+
+ ); + }) + } +

Albums

+ { + this.props.searchResults.albums.album.map((el, i) => { + return ( +
+ +
+
{el.name}
+
by {el.artist}
+
+
+ ); + }) + } +
-
- ); + ); + } } } diff --git a/app/components/SidebarMenu.css b/app/components/SidebarMenu.css index a21b7ad068..38e62fa5ea 100644 --- a/app/components/SidebarMenu.css +++ b/app/components/SidebarMenu.css @@ -1,5 +1,6 @@ .sidebar { - z-index: 10; + position: absolute; + z-index: 50; font-family: Questrial; font-size: 20px; font-weight: bold; @@ -57,6 +58,26 @@ font-weight: normal; } +.sidebar_search_spinner { + position: absolute; + display: inline-block; + top: 84px; + left: 245px; + text-align: center; +} + +.sidebar_search_clear { + position: absolute; + display: inline-block; + top: 80px; + left: 250px; + text-align: center; +} + +.sidebar_visible { + display: inline-block; +} + .sidebar_search_field:focus { border: 0px; } diff --git a/app/components/SidebarMenu.js b/app/components/SidebarMenu.js index 4a8ca76628..238b5f4d45 100644 --- a/app/components/SidebarMenu.js +++ b/app/components/SidebarMenu.js @@ -9,17 +9,69 @@ import styles from './SidebarMenu.css'; const path = require('path'); const enums = require('../api/Enum'); +const lastfm = require('../api/Lastfm'); + export default class SidebarMenu extends Component { constructor(props) { super(props); this.state = { - searching: false + searching: false, + searchValue: '', + searchSidebarOpen: false, + searchResults: null }; } handleSearch(event, value) { - console.log(event.target.value); + this.setState({ + searching: true, + searchValue: event.target.value + }); + + var albumPromise = new Promise((resolve, reject) => { + + lastfm.albumSearch(this.state.searchValue, (response) => { + resolve({albums: response.data.results.albummatches}); + }, 3); + + }); + + var artistPromise = new Promise((resolve, reject) => { + + lastfm.artistSearch(this.state.searchValue, (response) => { + resolve({artists: response.data.results.artistmatches}); + }, 3); + + }); + + var trackPromise = new Promise((resolve, reject) => { + + lastfm.trackSearch(this.state.searchValue, (response) => { + resolve({tracks: response.data.results.trackmatches}); + }, 3); + + }) + + Promise.all([albumPromise, artistPromise, trackPromise]) + .then(values => { + this.setState({ + searching: false, + searchSidebarOpen: true, + searchResults: Object.assign(values[0], values[1], values[2]) + }); + }); + + } + + handleClear(event, value) { + this.debounceInput.value = ''; + this.setState({ + searching: false, + searchValue: '', + searchSidebarOpen: true, + searchResults: null + }); } renderGoBack() { @@ -31,10 +83,21 @@ export default class SidebarMenu extends Component { } renderDefault() { + + var spinnerStyle = {}; + var clearStyle = {}; + + if (!this.state.searching) { + spinnerStyle.display = 'none'; + } + + if (this.state.searchValue.length == 0 || this.state.searching) { + clearStyle.display = 'none'; + } + var contents = []; contents.push( -
@@ -46,12 +109,20 @@ export default class SidebarMenu extends Component { placeholder="Search..." minLength={2} debounceTimeout={500} - onChange={this.handleSearch} + onChange={this.handleSearch.bind(this)} + ref={(input) => { this.debounceInput = input; }} + value={this.state.searchValue} autoFocus /> + + + +
- {/* */} +
); diff --git a/app/containers/SearchSidebarContainer.js b/app/containers/SearchSidebarContainer.js index cd22a8fe42..33524c9786 100644 --- a/app/containers/SearchSidebarContainer.js +++ b/app/containers/SearchSidebarContainer.js @@ -8,6 +8,10 @@ export default class SearchSidebarContainer extends Component { } render() { - return ; + return( + + ); } }