Skip to content

Commit

Permalink
Unified search bar
Browse files Browse the repository at this point in the history
  • Loading branch information
nukeop committed May 20, 2017
1 parent 13103d4 commit 832e03a
Show file tree
Hide file tree
Showing 6 changed files with 265 additions and 20 deletions.
43 changes: 37 additions & 6 deletions app/api/Lastfm.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
Expand Down Expand Up @@ -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);
});
Expand Down Expand Up @@ -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,
Expand All @@ -177,6 +207,7 @@ module.exports = {
getAlbumInfo: getAlbumInfo,
albumSearch: albumSearch,
artistSearch: artistSearch,
trackSearch: trackSearch,
getArtistInfo: getArtistInfo,
getArtistTopTracks: getArtistTopTracks,
getArtistTopAlbums: getArtistTopAlbums,
Expand Down
77 changes: 75 additions & 2 deletions app/components/SearchSidebar.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
55 changes: 50 additions & 5 deletions app/components/SearchSidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,57 @@ export default class SearchSidebar extends Component {
}

render() {
return (
<div className={styles.search_sidebar_container}>
<div className={styles.search_sidebar}>

if (this.props.searchResults === null) {
return null;
} else {
console.log(this.props.searchResults);

return (
<div className={styles.search_sidebar_container}>
<div className={styles.search_sidebar}>
<h3>Artists</h3>
{
this.props.searchResults.artists.artist.map((el, i) => {
return (
<div className={styles.search_sidebar_artist_container}>
<img src={el.image[1]['#text']} />
<span className={styles.search_sidebar_artist_name}>{el.name}</span>
</div>
);
})
}
<h3>Songs</h3>
{
this.props.searchResults.tracks.track.map((el, i) => {
return (
<div className={styles.search_sidebar_track_container}>
<img src={el.image[1]['#text']} />
<div className={styles.search_sidebar_track_info}>
<div className={styles.search_sidebar_track_name}>{el.name}</div>
<div className={styles.search_sidebar_track_artist}>by {el.artist}</div>
</div>
</div>
);
})
}
<h3>Albums</h3>
{
this.props.searchResults.albums.album.map((el, i) => {
return (
<div className={styles.search_sidebar_album_container}>
<img src={el.image[1]['#text']} />
<div className={styles.search_sidebar_album_info}>
<div className={styles.search_sidebar_album_name}>{el.name}</div>
<div className={styles.search_sidebar_album_artist}>by {el.artist}</div>
</div>
</div>
);
})
}
</div>
</div>
</div>
);
);
}
}
}
23 changes: 22 additions & 1 deletion app/components/SidebarMenu.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.sidebar {
z-index: 10;
position: absolute;
z-index: 50;
font-family: Questrial;
font-size: 20px;
font-weight: bold;
Expand Down Expand Up @@ -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;
}
Expand Down
81 changes: 76 additions & 5 deletions app/components/SidebarMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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(

<div style={{flex: '0 0 auto'}}>
<div className={styles.sidebar_brand_cell}>
<img src={path.join(__dirname, "../media/nuclear/logo_full_light.png")} height="36"/>
Expand All @@ -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
/>
<i style={spinnerStyle} className={`${styles.sidebar_search_spinner} ` + 'fa fa-spinner fa-pulse fa-fw'} />
<a style={clearStyle} href="#" onClick={this.handleClear.bind(this)} className={styles.sidebar_search_clear}>
<i className='fa fa-times' />
</a>
</div>

{/* <SearchSidebarContainer /> */}
<SearchSidebarContainer
searchResults={this.state.searchResults}
/>
</div>
);

Expand Down
6 changes: 5 additions & 1 deletion app/containers/SearchSidebarContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ export default class SearchSidebarContainer extends Component {
}

render() {
return <SearchSidebar />;
return(
<SearchSidebar
searchResults={this.props.searchResults}
/>
);
}
}

0 comments on commit 832e03a

Please sign in to comment.