Using idle event instead of bounds_changed

This commit is contained in:
Vesa Luusua 2017-08-22 14:30:28 +03:00
parent 9305aa76e1
commit 30007a085f
3 changed files with 49 additions and 26 deletions

View file

@ -53,7 +53,7 @@ const MapWithGoogleMap = withGoogleMap(props => {
isOpenOnModal,
listings,
listingOpen,
onBoundsChanged,
onIdle,
onCloseAsModal,
onListingClicked,
onMapLoad,
@ -76,7 +76,11 @@ const MapWithGoogleMap = withGoogleMap(props => {
});
const openedCard = listingOpen
? <SearchMapListingCard key={listingOpen.id.uuid} listing={listingOpen} onClickCallback={onCloseAsModal} />
? <SearchMapListingCard
key={listingOpen.id.uuid}
listing={listingOpen}
onClickCallback={onCloseAsModal}
/>
: null;
return (
@ -93,7 +97,7 @@ const MapWithGoogleMap = withGoogleMap(props => {
fullscreenControl: !isOpenOnModal,
}}
ref={onMapLoad}
onBoundsChanged={onBoundsChanged}
onIdle={onIdle}
>
{priceLabels}
{openedCard}
@ -127,7 +131,7 @@ export class SearchMapComponent extends Component {
// Do not call fitMapToBounds if bounds are the same.
// Our bounds are viewport bounds, and fitBounds will try to add margins around those bounds
// that would result to zoom-loop (bound change -> fitmap -> bounds change -> ...)
if (!isEqual(nextProps.bounds, currentBounds)) {
if (!isEqual(nextProps.bounds, currentBounds) && nextProps.useLocationSearchBounds) {
fitMapToBounds(this.googleMap, nextProps.bounds);
}
}
@ -166,7 +170,7 @@ export class SearchMapComponent extends Component {
center,
isOpenOnModal,
listings,
onBoundsChanged,
onIdle,
onCloseAsModal,
zoom,
} = this.props;
@ -185,8 +189,8 @@ export class SearchMapComponent extends Component {
listingOpen={this.state.listingOpen}
onListingClicked={this.onListingClicked}
onMapLoad={this.onMapLoadHandler}
onBoundsChanged={() => {
onBoundsChanged(this.googleMap);
onIdle={() => {
onIdle(this.googleMap);
}}
onCloseAsModal={() => {
if (onCloseAsModal) {
@ -204,6 +208,7 @@ SearchMapComponent.defaultProps = {
className: '',
rootClassName: null,
mapRootClassName: null,
useLocationSearchBounds: true,
bounds: null,
center: new sdkTypes.LatLng(0, 0),
isOpenOnModal: false,
@ -221,7 +226,8 @@ SearchMapComponent.propTypes = {
isOpenOnModal: bool,
listings: arrayOf(propTypes.listing),
mapRootClassName: string,
onBoundsChanged: func.isRequired,
useLocationSearchBounds: bool, // eslint-disable-line react/no-unused-prop-types
onIdle: func.isRequired,
onCloseAsModal: func,
rootClassName: string,
zoom: number,

View file

@ -26,8 +26,8 @@ import css from './SearchPage.css';
const RESULT_PAGE_SIZE = 12;
const SHARETRIBE_API_MAX_PAGE_SIZE = 100;
const MAX_SEARCH_RESULT_PAGES_ON_MAP = 5; // 100 * 5 = 500 listings are shown on a map.
const DEBOUNCE_MAP_BOUNDS_CHANGE = 500; // bounds_change event is fired too often while dragging
const MODAL_BREAKPOINT = 768; /* Search is in modal on mobile layout */
const MODAL_BREAKPOINT = 768; // Search is in modal on mobile layout
const SEARCH_WITH_MAP_DEBOUNCE = 300; // Little bit of debounce before search is initiated.
const pickSearchParamsOnly = params => {
const { address, origin, bounds } = params || {};
@ -48,8 +48,9 @@ export class SearchPageComponent extends Component {
// we need to by pass 2nd search created by initial 'bounds_changes' event
this.useLocationSearchBounds = true;
this.modalOpenedBoundsChange = false;
this.searchMapListingsInProgress = false;
this.onBoundsChanged = debounce(this.onBoundsChanged.bind(this), DEBOUNCE_MAP_BOUNDS_CHANGE);
this.onIdle = debounce(this.onIdle.bind(this), SEARCH_WITH_MAP_DEBOUNCE);
this.fetchMoreListingsToMap = this.fetchMoreListingsToMap.bind(this);
}
@ -72,7 +73,9 @@ export class SearchPageComponent extends Component {
}
}
onBoundsChanged(googleMap) {
// We are using Google Maps idle event instead of bounds_changed, since it will not be fired
// too often (in the middle of map's pan or zoom activity)
onIdle(googleMap) {
const { flattenedRoutes, history, location } = this.props;
const { address, country, boundsChanged } = parse(location.search, {
@ -105,6 +108,7 @@ export class SearchPageComponent extends Component {
const perPage = SHARETRIBE_API_MAX_PAGE_SIZE;
const page = 1;
const searchParamsForMapResults = { ...searchInURL, page, perPage };
this.searchMapListingsInProgress = true;
// Search more listings for map
onSearchMapListings(searchParamsForMapResults)
@ -113,6 +117,8 @@ export class SearchPageComponent extends Component {
page < MAX_SEARCH_RESULT_PAGES_ON_MAP;
if (hasNextPage) {
onSearchMapListings({ ...searchParamsForMapResults, page: page + 1 });
} else {
this.searchMapListingsInProgress = false;
}
})
.catch(error => {
@ -205,11 +211,12 @@ export class SearchPageComponent extends Component {
bounds={bounds}
center={origin}
listings={mapListings || []}
onBoundsChanged={this.onBoundsChanged}
onIdle={this.onIdle}
isOpenOnModal={this.state.isSearchMapOpenOnMobile}
onCloseAsModal={() => {
onManageDisableScrolling('SearchPage.map', false);
}}
useLocationSearchBounds={this.useLocationSearchBounds}
/>
);
const showSearchMapInMobile = this.state.isSearchMapOpenOnMobile ? searchMap : null;
@ -247,7 +254,11 @@ export class SearchPageComponent extends Component {
{listingsAreLoaded && totalItems === 0 ? noResults : null}
{searchInProgress ? loadingResults : null}
</div>
<div className={classNames(css.listings, { [css.newSearchInProgress]: !listingsAreLoaded })}>
<div
className={classNames(css.listings, {
[css.newSearchInProgress]: !listingsAreLoaded,
})}
>
<SearchResultsPanel
className={css.searchListingsPanel}
currencyConfig={config.currencyConfig}
@ -256,7 +267,9 @@ export class SearchPageComponent extends Component {
search={searchParamsForPagination}
>
<button
className={classNames(css.openMobileMap, { [css.openMobileMapSticky] : listings.length > 0 })}
className={classNames(css.openMobileMap, {
[css.openMobileMapSticky]: listings.length > 0,
})}
onClick={() => {
this.useLocationSearchBounds = true;
this.modalOpenedBoundsChange = true;

View file

@ -35,7 +35,8 @@ exports[`SearchPageComponent matches snapshot 1`] = `
} />
</h2>
</div>
<div>
<div
className="">
<SearchResultsPanel
className={null}
currencyConfig={
@ -59,16 +60,18 @@ exports[`SearchPageComponent matches snapshot 1`] = `
}
}
rootClassName={null}
search={Object {}} />
search={Object {}}>
<button
className=""
onClick={[Function]}>
<MapIcon
className={null} />
<FormattedMessage
id="SearchPage.openMapView"
values={Object {}} />
</button>
</SearchResultsPanel>
</div>
<button
onClick={[Function]}>
<MapIcon
className={null} />
<FormattedMessage
id="SearchPage.openMapView"
values={Object {}} />
</button>
</div>
<withViewport(ModalInMobileComponent)
id="SearchPage.map"
@ -89,8 +92,9 @@ exports[`SearchPageComponent matches snapshot 1`] = `
isOpenOnModal={false}
listings={Array []}
mapRootClassName={null}
onBoundsChanged={[Function]}
mapSearchInProgress={false}
onCloseAsModal={[Function]}
onIdle={[Function]}
rootClassName={null}
zoom={11} />
</div>