Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions client/src/components/PackageSearch/Client.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
import fetch from 'isomorphic-fetch'

function search (query, range, dev, cb) {
function serialize (obj) {
let str = []
for (let property in obj) {
if (obj.hasOwnProperty(property)) {
str.push(encodeURIComponent(property) + '=' + encodeURIComponent(obj[property]))
}
}
return str.join('&')
}

function search (query, range, dev, limit, gt, cb) {
query = encodeURIComponent(query)
range = encodeURIComponent(range)

return fetch(`/api/query/${query}${range ? '/' : ''}${range}${dev ? '?dev=1' : ''}`, {
const options = Object.assign({}, { limit: -1 }, {limit, gt})

if (dev) {
options.dev = 1
}

return fetch(`/api/query/${query}${range ? '/' : ''}${range}?${serialize(options)}`, {
accept: 'application/json'
}).then(checkStatus)
.then(parseJSON)
Expand Down
101 changes: 93 additions & 8 deletions client/src/components/PackageSearch/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ import './style.css'
const resetState = {
results: null,
isLoading: false,
errorMessage: ''
isLoadingMore: false,
errorMessage: '',
lastPackage: ''
}

const resultsLimit = 50

const PackageSearch = React.createClass({
getResetState (name, range, dev) {
let state = Object.assign({}, resetState, {})
Expand Down Expand Up @@ -97,7 +101,8 @@ const PackageSearch = React.createClass({
runSearch (
name = this.state.searchValueForName,
range = this.state.searchValueForRange,
dev = this.state.searchDev
dev = this.state.searchDev,
lastPackage = this.state.lastPackage
) {
if (name === '') {
return false
Expand All @@ -118,7 +123,50 @@ const PackageSearch = React.createClass({

let _name = name

Client.search(name, range, dev, (result) => {
Client.search(name, range, dev, resultsLimit, lastPackage, (result) => {
if (result.error) {
let errorState = Object.assign({}, resetState, {
errorMessage: result.message
})

this.setState(errorState)
} else {
this.setState({
results: lastPackage ? this.state.results.concat(result) : result,
queryName: _name,
isLoading: false,
lastPackage: result.length === resultsLimit ? result[result.length - 1].name : ''
})
}
})
},

runSearchForMore (
name = this.state.searchValueForName,
range = this.state.searchValueForRange,
dev = this.state.searchDev,
lastPackage = this.state.lastPackage
) {
if (name === '') {
return false
}

if (range === '') {
this.setState({
searchValueForRange: '*'
})
}

dev = Boolean(dev)

this.setState({
errorMessage: '',
isLoadingMore: true
})

let _name = name

Client.search(name, range, dev, resultsLimit, lastPackage, (result) => {
if (result.error) {
let errorState = Object.assign({}, resetState, {
errorMessage: result.message
Expand All @@ -127,14 +175,19 @@ const PackageSearch = React.createClass({
this.setState(errorState)
} else {
this.setState({
results: result,
results: lastPackage ? this.state.results.concat(result) : result,
queryName: _name,
isLoading: false
isLoadingMore: false,
lastPackage: result.length === resultsLimit ? result[result.length - 1].name : ''
})
}
})
},

loadMore () {
this.runSearchForMore()
},

componentWillReceiveProps (nextProps) {
// Run search if new params are different from current ones
let packageParam = nextProps.params.package
Expand All @@ -148,6 +201,26 @@ const PackageSearch = React.createClass({
})
},

componentDidMount () {
window.addEventListener('scroll', this.handleScroll)
},

componentWillUnmount () {
window.removeEventListener('scroll', this.handleScroll)
},

handleScroll () {
// @see http://stackoverflow.com/a/22394544/1955940
const scrollTop = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop
const scrollHeight = (document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight

if ((scrollTop + window.innerHeight) >= scrollHeight) {
if (this.state.lastPackage) {
this.loadMore()
}
}
},

componentWillMount () {
// Run search when mounting component
// eg. when hitting a deep link
Expand Down Expand Up @@ -293,17 +366,29 @@ const PackageSearch = React.createClass({

<div className='ui hidden divider' />
<div className='ui container ResultsContainer'>
{ this.state.isLoading ? (
{this.state.isLoading ? (
<div className='ui active inverted dimmer'>
<div className='ui medium text loader'>
<b>Loading</b>
<p>
Searching for popular modules may take a while.
</p>
</p>
</div>
</div>
) : null}
<SearchResults {...this.state} />
{this.state.lastPackage &&
<div className='ui container ResultsPagination'>
<button
type='submit'
className={`ui column large teal button ${this.state.isLoadingMore ? 'disabled' : ''}`}
onClick={this.loadMore}
disabled={this.state.isLoadingMore}
>
{this.state.isLoadingMore ? 'Loading...' : 'Load more'}
</button>
</div>
}
</div>
</div>
)
Expand Down Expand Up @@ -380,7 +465,7 @@ function SearchResultsCount ({ results }) {
class SearchResultsModules extends React.Component {
shouldComponentUpdate (nextProps) {
return (
nextProps.queryName !== this.props.queryName
nextProps.queryName !== this.props.queryName || nextProps.lastPackage !== this.props.lastPackage
)
}

Expand Down
5 changes: 5 additions & 0 deletions client/src/components/PackageSearch/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,8 @@
.SearchForm .ui.large.toggle.checkbox input:checked~label:before {
background-color: #00b5ad!important;
}

.ResultsPagination {
margin-top: 25px;
text-align: center;
}