Skip to content
Closed
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
47 changes: 47 additions & 0 deletions modules/search/instant-search/components/scroll-button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/** @jsx h */

/**
* External dependencies
*/
import { h, Component } from 'preact';
import { __ } from '@wordpress/i18n';
// NOTE: We only import the debounce package here for to reduced bundle size.
// Do not import the entire lodash library!
// eslint-disable-next-line lodash/import-scope
import debounce from 'lodash/debounce';

class ScrollButton extends Component {
componentDidMount() {
this.props.enableAutoScrolling && document.addEventListener( 'scroll', this.checkScroll );
}
componentDidUnmount() {
document.removeEventListener( 'scroll', this.checkScroll );
}

checkScroll = debounce( () => {
if (
this.props.enableAutoScrolling &&
window.innerHeight + window.scrollY === document.body.offsetHeight
) {
this.props.onClick();
}
}, 100 );

render() {
return (
<button
className="jetpack-instant-search__more-button"
disabled={ this.props.isLoading }
onclick={ this.props.onClick }
>
{ this.props.isLoading ? (
<span>{ __( 'Loading results…', 'jetpack' ) }</span>
) : (
<span>{ __( 'Load more results', 'jetpack' ) }</span>
) }
</button>
);
}
}

export default ScrollButton;
9 changes: 9 additions & 0 deletions modules/search/instant-search/components/search-results.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { h, Component } from 'preact';
* Internal dependencies
*/
import SearchResultMinimal from './search-result-minimal';
import ScrollButton from './scroll-button';

class SearchResults extends Component {
render_result( result ) {
Expand All @@ -24,6 +25,7 @@ class SearchResults extends Component {

render() {
const { results = [], query, total = 0, corrected_query = false } = this.props;

if ( query === '' ) {
return <div className="jetpack-instant-search__search-results" />;
}
Expand Down Expand Up @@ -53,6 +55,13 @@ class SearchResults extends Component {
</p>
) }
{ results.map( result => this.render_result( result ) ) }
{ this.props.hasNextPage && (
<ScrollButton
enableAutoScrolling
isLoading={ this.props.isLoading }
onClick={ this.props.onLoadNextPage }
/>
) }
</div>
);
}
Expand Down
64 changes: 46 additions & 18 deletions modules/search/instant-search/components/search-widget.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,17 @@ class SearchApp extends Component {
super( ...arguments );
this.input = Preact.createRef();
this.requestId = 0;

// TODO: Rework these lines. We shouldn't reassign properties.
this.props.resultFormat = 'minimal';
this.props.aggregations = buildFilterAggregations( this.props.options.widgets );
this.props.widgets = this.props.options.widgets ? this.props.options.widgets : [];

this.state = {
isLoading: false,
query: this.props.initialValue,
response: {},
sort: this.props.initialSort,
results: {},
};
this.getResults = debounce( this.getResults, 500 );
this.getResults( this.state.query, getFilterQuery(), this.state.sort );
Expand Down Expand Up @@ -72,30 +76,51 @@ class SearchApp extends Component {
this.getResults( this.state.query, getFilterQuery(), getSortQuery() );
};

getResults = ( query, filter, sort ) => {
getResults = ( query, filter, sort, pageHandle ) => {
if ( query ) {
this.requestId++;
const requestId = this.requestId;

search( {
aggregations: this.props.aggregations,
filter,
query,
resultFormat: this.props.options.resultFormat,
siteId: this.props.options.siteId,
sort,
} ).then( results => {
if ( this.requestId === requestId ) {
this.setState( { results } );
}
this.setState( { isLoading: true }, () => {
search( {
// Skip aggregations when requesting for paged results
aggregations: !! pageHandle ? this.props.aggregations : {},
filter,
pageHandle,
query,
resultFormat: this.props.options.resultFormat,
siteId: this.props.options.siteId,
sort,
} ).then( newResponse => {
if ( this.requestId === requestId ) {
const response = { ...newResponse };
if ( !! pageHandle ) {
response.results = [
...( 'results' in this.state.response ? this.state.response.results : [] ),
...newResponse.results,
];
}
this.setState( { response } );
}
this.setState( { isLoading: false } );
} );
} );
} else {
this.setState( { results: [] } );
this.setState( { response: {}, isLoading: false } );
}
};

loadNextPage = () => {
this.getResults(
this.state.query,
getFilterQuery(),
getSortQuery(),
this.state.response.page_handle
);
};

render() {
const { query, results } = this.state;
const { query, response, isLoading } = this.state;
return (
<Preact.Fragment>
{ this.props.widgets.map( ( widget, index ) => (
Expand Down Expand Up @@ -127,7 +152,7 @@ class SearchApp extends Component {
initialValues={ this.props.initialFilters }
onChange={ this.onChangeFilter }
postTypes={ this.props.options.postTypes }
results={ this.state.results }
results={ this.state.response }
widget={ widget }
/>
</div>
Expand All @@ -136,9 +161,12 @@ class SearchApp extends Component {

<Portal into="main">
<SearchResults
hasNextPage={ !! response.page_handle }
isLoading={ isLoading }
onLoadNextPage={ this.loadNextPage }
query={ query }
{ ...results }
result_format={ this.props.options.resultFormat }
resultFormat={ this.props.options.resultFormat }
{ ...response }
/>
</Portal>
</Preact.Fragment>
Expand Down
3 changes: 2 additions & 1 deletion modules/search/instant-search/lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function buildFilterObject( filterQuery ) {
return filter;
}

export function search( { aggregations, filter, query, resultFormat, siteId, sort } ) {
export function search( { aggregations, filter, pageHandle, query, resultFormat, siteId, sort } ) {
let fields = [];
let highlight_fields = [];
switch ( resultFormat ) {
Expand Down Expand Up @@ -145,6 +145,7 @@ export function search( { aggregations, filter, query, resultFormat, siteId, sor
filter: buildFilterObject( filter ),
query: encodeURIComponent( query ),
sort,
page_handle: pageHandle,
} )
);

Expand Down