From 417e72dff260659b76d6d6ba71a788bd62ec2f08 Mon Sep 17 00:00:00 2001 From: Vesa Luusua Date: Tue, 22 Aug 2017 14:02:06 +0300 Subject: [PATCH 1/5] Don't lose old search listings, make them transparent while searching new stuff --- src/containers/SearchPage/SearchPage.css | 5 +++++ src/containers/SearchPage/SearchPage.duck.js | 1 - src/containers/SearchPage/SearchPage.js | 5 +++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/containers/SearchPage/SearchPage.css b/src/containers/SearchPage/SearchPage.css index 0ec447b2..b9dc3cb2 100644 --- a/src/containers/SearchPage/SearchPage.css +++ b/src/containers/SearchPage/SearchPage.css @@ -69,6 +69,11 @@ flex-direction: column; } +.newSearchInProgress { + opacity: 0.1; + transition: opacity var(--transitionStyleButton); +} + .searchListingsPanel { flex-grow: 1; } diff --git a/src/containers/SearchPage/SearchPage.duck.js b/src/containers/SearchPage/SearchPage.duck.js index 98212b71..2cf93864 100644 --- a/src/containers/SearchPage/SearchPage.duck.js +++ b/src/containers/SearchPage/SearchPage.duck.js @@ -33,7 +33,6 @@ const listingPageReducer = (state = initialState, action = {}) => { ...state, searchParams: payload.searchParams, searchInProgress: true, - currentPageResultIds: [], searchMapListingIds: [], searchListingsError: null, }; diff --git a/src/containers/SearchPage/SearchPage.js b/src/containers/SearchPage/SearchPage.js index fa44d219..0e7593d4 100644 --- a/src/containers/SearchPage/SearchPage.js +++ b/src/containers/SearchPage/SearchPage.js @@ -4,6 +4,7 @@ import { connect } from 'react-redux'; import { compose } from 'redux'; import { withRouter } from 'react-router-dom'; import { debounce, isEqual, unionWith } from 'lodash'; +import classNames from 'classnames'; import config from '../../config'; import { withFlattenedRoutes } from '../../util/contextHelpers'; import { googleLatLngToSDKLatLng, googleBoundsToSDKBounds } from '../../util/googleMaps'; @@ -246,11 +247,11 @@ export class SearchPageComponent extends Component { {listingsAreLoaded && totalItems === 0 ? noResults : null} {searchInProgress ? loadingResults : null} -
+
From 9305aa76e1250ee2001a027bd51b79778bf414e6 Mon Sep 17 00:00:00 2001 From: Vesa Luusua Date: Tue, 22 Aug 2017 14:20:23 +0300 Subject: [PATCH 2/5] mobile open map modal button as sticky (not compatible: Edge < 16) --- .../SearchResultsPanel/SearchResultsPanel.css | 1 + .../SearchResultsPanel/SearchResultsPanel.js | 5 +++- src/containers/SearchPage/SearchPage.css | 4 +++ src/containers/SearchPage/SearchPage.js | 25 ++++++++++--------- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/components/SearchResultsPanel/SearchResultsPanel.css b/src/components/SearchResultsPanel/SearchResultsPanel.css index 5b31ec3e..0c529d4e 100644 --- a/src/components/SearchResultsPanel/SearchResultsPanel.css +++ b/src/components/SearchResultsPanel/SearchResultsPanel.css @@ -6,6 +6,7 @@ } .listingCards { + flex-grow: 1; padding: 0 24px 24px 24px; @media (--viewportMedium) { diff --git a/src/components/SearchResultsPanel/SearchResultsPanel.js b/src/components/SearchResultsPanel/SearchResultsPanel.js index 7dd0dfbd..666b2a02 100644 --- a/src/components/SearchResultsPanel/SearchResultsPanel.js +++ b/src/components/SearchResultsPanel/SearchResultsPanel.js @@ -28,6 +28,7 @@ const SearchResultsPanel = props => { currencyConfig={currencyConfig} /> ))} + {props.children}
{paginationLinks}
@@ -35,6 +36,7 @@ const SearchResultsPanel = props => { }; SearchResultsPanel.defaultProps = { + children: null, className: null, listings: [], pagination: null, @@ -42,9 +44,10 @@ SearchResultsPanel.defaultProps = { search: null, }; -const { array, object, string } = PropTypes; +const { array, node, object, string } = PropTypes; SearchResultsPanel.propTypes = { + children: node, className: string, currencyConfig: propTypes.currencyConfig.isRequired, listings: array, diff --git a/src/containers/SearchPage/SearchPage.css b/src/containers/SearchPage/SearchPage.css index b9dc3cb2..a64174b9 100644 --- a/src/containers/SearchPage/SearchPage.css +++ b/src/containers/SearchPage/SearchPage.css @@ -117,6 +117,10 @@ } } +.openMobileMapSticky { + position: sticky; +} + .mapPanel { @media (--viewportMedium) { diff --git a/src/containers/SearchPage/SearchPage.js b/src/containers/SearchPage/SearchPage.js index 0e7593d4..24cf3abf 100644 --- a/src/containers/SearchPage/SearchPage.js +++ b/src/containers/SearchPage/SearchPage.js @@ -254,19 +254,20 @@ export class SearchPageComponent extends Component { listings={listings} pagination={listingsAreLoaded ? pagination : null} search={searchParamsForPagination} - /> + > + + - Date: Tue, 22 Aug 2017 14:30:28 +0300 Subject: [PATCH 3/5] Using idle event instead of bounds_changed --- src/components/SearchMap/SearchMap.js | 22 +++++++++------ src/containers/SearchPage/SearchPage.js | 27 ++++++++++++++----- .../__snapshots__/SearchPage.test.js.snap | 26 ++++++++++-------- 3 files changed, 49 insertions(+), 26 deletions(-) diff --git a/src/components/SearchMap/SearchMap.js b/src/components/SearchMap/SearchMap.js index add46d98..b62b9408 100644 --- a/src/components/SearchMap/SearchMap.js +++ b/src/components/SearchMap/SearchMap.js @@ -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 - ? + ? : 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, diff --git a/src/containers/SearchPage/SearchPage.js b/src/containers/SearchPage/SearchPage.js index 24cf3abf..a61510a2 100644 --- a/src/containers/SearchPage/SearchPage.js +++ b/src/containers/SearchPage/SearchPage.js @@ -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} -
+
-
+
+ search={Object {}}> + +
-
From b7445a6cb1f2e3432f1fa4aa8d469edaa628bc57 Mon Sep 17 00:00:00 2001 From: Vesa Luusua Date: Tue, 22 Aug 2017 14:31:11 +0300 Subject: [PATCH 4/5] Sharetribe account related key for google maps --- public/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index a824b333..3bf5a051 100644 --- a/public/index.html +++ b/public/index.html @@ -54,7 +54,7 @@
- +