diff --git a/src/components/LocationAutocompleteInput/GeocoderGoogleMaps.js b/src/components/LocationAutocompleteInput/GeocoderGoogleMaps.js
index 9af86748..b276f9d5 100644
--- a/src/components/LocationAutocompleteInput/GeocoderGoogleMaps.js
+++ b/src/components/LocationAutocompleteInput/GeocoderGoogleMaps.js
@@ -1,39 +1,21 @@
import React from 'react';
-// import { types as sdkTypes } from '../../util/sdkLoader';
import classNames from 'classnames';
import { getPlacePredictions, getPlaceDetails, locationBounds } from '../../util/googleMaps';
import { userLocation } from '../../util/maps';
+import config from '../../config';
+
import css from './LocationAutocompleteInput.css';
-// const { LatLng: SDKLatLng, LatLngBounds: SDKLatLngBounds } = sdkTypes;
-
export const CURRENT_LOCATION_ID = 'current-location';
-const CURRENT_LOCATION_BOUNDS_DISTANCE = 1000; // meters
// A list of default predictions that can be shown when the user
// focuses on the autocomplete input without typing a search. This can
// be used to reduce typing and Geocoding API calls for common
// searches.
-export const defaultPredictions = [
- // Examples:
- // Current user location from the browser geolocation API
- // {
- // id: CURRENT_LOCATION_ID,
- // predictionPlace: {},
- // },
- // Helsinki
- // {
- // id: 'default-helsinki',
- // predictionPlace: {
- // address: 'Helsinki, Finland',
- // origin: new SDKLatLng(60.16985, 24.93837),
- // bounds: new SDKLatLngBounds(
- // new SDKLatLng(60.29783, 25.25448),
- // new SDKLatLng(59.92248, 24.78287)
- // ),
- // },
- // },
-];
+export const defaultPredictions = (config.maps.search.suggestCurrentLocation
+ ? [{ id: CURRENT_LOCATION_ID, predictionPlace: {} }]
+ : []
+).concat(config.maps.search.defaults);
// When displaying data from the Google Maps Places API, and
// attribution is required next to the results.
@@ -117,7 +99,7 @@ class GeocoderGoogleMaps {
return {
address: '',
origin: latlng,
- bounds: locationBounds(latlng, CURRENT_LOCATION_BOUNDS_DISTANCE),
+ bounds: locationBounds(latlng, config.maps.search.currentLocationBoundsDistance),
};
});
}
diff --git a/src/components/LocationAutocompleteInput/GeocoderMapbox.js b/src/components/LocationAutocompleteInput/GeocoderMapbox.js
index 2b830026..f4bd6d85 100644
--- a/src/components/LocationAutocompleteInput/GeocoderMapbox.js
+++ b/src/components/LocationAutocompleteInput/GeocoderMapbox.js
@@ -5,7 +5,6 @@ import config from '../../config';
const { LatLng: SDKLatLng, LatLngBounds: SDKLatLngBounds } = sdkTypes;
export const CURRENT_LOCATION_ID = 'current-location';
-const CURRENT_LOCATION_BOUNDS_DISTANCE = 1000; // meters
const locationBounds = (latlng, distance) => {
const bounds = new window.mapboxgl.LngLat(latlng.lng, latlng.lat).toBounds(distance);
@@ -38,26 +37,10 @@ const placeBounds = prediction => {
// focuses on the autocomplete input without typing a search. This can
// be used to reduce typing and Geocoding API calls for common
// searches.
-export const defaultPredictions = [
- // Examples:
- // Current user location from the browser geolocation API
- // {
- // id: CURRENT_LOCATION_ID,
- // predictionPlace: {},
- // },
- // Helsinki
- // {
- // id: 'default-helsinki',
- // predictionPlace: {
- // address: 'Helsinki, Finland',
- // origin: new SDKLatLng(60.16985, 24.93837),
- // bounds: new SDKLatLngBounds(
- // new SDKLatLng(60.29783, 25.25448),
- // new SDKLatLng(59.92248, 24.78287)
- // ),
- // },
- // },
-];
+export const defaultPredictions = (config.maps.search.suggestCurrentLocation
+ ? [{ id: CURRENT_LOCATION_ID, predictionPlace: {} }]
+ : []
+).concat(config.maps.search.defaults);
export const GeocoderAttribution = () => null;
@@ -140,7 +123,7 @@ class GeocoderMapbox {
return {
address: '',
origin: latlng,
- bounds: locationBounds(latlng, CURRENT_LOCATION_BOUNDS_DISTANCE),
+ bounds: locationBounds(latlng, config.maps.search.currentLocationBoundsDistance),
};
});
}
diff --git a/src/components/Map/DynamicGoogleMap.js b/src/components/Map/DynamicGoogleMap.js
index 306a3bc8..ae3f0e31 100644
--- a/src/components/Map/DynamicGoogleMap.js
+++ b/src/components/Map/DynamicGoogleMap.js
@@ -8,13 +8,13 @@ import config from '../../config';
* It handles some of the google map initialization states.
*/
const DynamicGoogleMap = withGoogleMap(props => {
- const { center, zoom, address, coordinatesConfig } = props;
+ const { center, zoom, address, mapsConfig } = props;
- const { markerURI, anchorX, anchorY, width, height } = coordinatesConfig.customMarker || {};
- const markerIcon = coordinatesConfig.customMarker
+ const { enabled, url, anchorX, anchorY, width, height } = mapsConfig.customMarker;
+ const markerIcon = enabled
? {
icon: {
- url: markerURI,
+ url,
// The origin for this image is (0, 0).
origin: new window.google.maps.Point(0, 0),
@@ -27,8 +27,15 @@ const DynamicGoogleMap = withGoogleMap(props => {
const marker = ;
const circleProps = {
- options: coordinatesConfig.circleOptions,
- radius: coordinatesConfig.coordinateOffset,
+ options: {
+ fillColor: mapsConfig.fuzzy.circleColor,
+ fillOpacity: 0.2,
+ strokeColor: mapsConfig.fuzzy.circleColor,
+ strokeOpacity: 0.5,
+ strokeWeight: 1,
+ clickable: false,
+ },
+ radius: mapsConfig.fuzzy.offset,
center,
};
@@ -59,7 +66,7 @@ const DynamicGoogleMap = withGoogleMap(props => {
},
}}
>
- {coordinatesConfig.fuzzy ? circle : marker}
+ {mapsConfig.fuzzy.enabled ? circle : marker}
);
});
@@ -67,8 +74,8 @@ const DynamicGoogleMap = withGoogleMap(props => {
DynamicGoogleMap.defaultProps = {
address: '',
center: null,
- zoom: config.coordinates.fuzzy ? config.coordinates.fuzzyDefaultZoomLevel : 11,
- coordinatesConfig: config.coordinates,
+ zoom: config.maps.fuzzy.enabled ? config.maps.fuzzy.defaultZoomLevel : 11,
+ mapsConfig: config.maps,
};
DynamicGoogleMap.propTypes = {
@@ -78,7 +85,7 @@ DynamicGoogleMap.propTypes = {
lng: number.isRequired,
}).isRequired,
zoom: number,
- coordinatesConfig: object,
+ mapsConfig: object,
};
export default DynamicGoogleMap;
diff --git a/src/components/Map/DynamicMapboxMap.js b/src/components/Map/DynamicMapboxMap.js
index e0fba3b3..38e365fa 100644
--- a/src/components/Map/DynamicMapboxMap.js
+++ b/src/components/Map/DynamicMapboxMap.js
@@ -4,25 +4,21 @@ import uniqueId from 'lodash/uniqueId';
import { circlePolyline } from '../../util/maps';
import config from '../../config';
-const mapMarker = coordinatesConfig => {
- const { customMarker } = coordinatesConfig;
- if (customMarker) {
+const mapMarker = mapsConfig => {
+ const { enabled, url, width, height } = mapsConfig.customMarker;
+ if (enabled) {
const element = document.createElement('div');
- element.style.backgroundImage = `url(${customMarker.markerURI})`;
- element.style.width = `${customMarker.width}px`;
- element.style.height = `${customMarker.height}px`;
+ element.style.backgroundImage = `url(${url})`;
+ element.style.width = `${width}px`;
+ element.style.height = `${height}px`;
return new window.mapboxgl.Marker({ element });
} else {
return new window.mapboxgl.Marker();
}
};
-const circleLayer = (center, coordinatesConfig, layerId) => {
- const { fillColor, fillOpacity } = coordinatesConfig.circleOptions;
- const path = circlePolyline(center, coordinatesConfig.coordinateOffset).map(([lat, lng]) => [
- lng,
- lat,
- ]);
+const circleLayer = (center, mapsConfig, layerId) => {
+ const path = circlePolyline(center, mapsConfig.fuzzy.offset).map(([lat, lng]) => [lng, lat]);
return {
id: layerId,
type: 'fill',
@@ -37,8 +33,8 @@ const circleLayer = (center, coordinatesConfig, layerId) => {
},
},
paint: {
- 'fill-color': fillColor,
- 'fill-opacity': fillOpacity,
+ 'fill-color': mapsConfig.fuzzy.circleColor,
+ 'fill-opacity': 0.2,
},
};
};
@@ -59,7 +55,7 @@ class DynamicMapboxMap extends Component {
this.updateFuzzyCirclelayer = this.updateFuzzyCirclelayer.bind(this);
}
componentDidMount() {
- const { center, zoom, coordinatesConfig } = this.props;
+ const { center, zoom, mapsConfig } = this.props;
const position = [center.lng, center.lat];
this.map = new window.mapboxgl.Map({
@@ -71,12 +67,12 @@ class DynamicMapboxMap extends Component {
});
this.map.addControl(new window.mapboxgl.NavigationControl(), 'top-left');
- if (coordinatesConfig.fuzzy) {
+ if (mapsConfig.fuzzy.enabled) {
this.map.on('load', () => {
- this.map.addLayer(circleLayer(center, coordinatesConfig, this.fuzzyLayerId));
+ this.map.addLayer(circleLayer(center, mapsConfig, this.fuzzyLayerId));
});
} else {
- this.centerMarker = mapMarker(coordinatesConfig);
+ this.centerMarker = mapMarker(mapsConfig);
this.centerMarker.setLngLat(position).addTo(this.map);
}
}
@@ -92,7 +88,7 @@ class DynamicMapboxMap extends Component {
return;
}
- const { center, zoom, coordinatesConfig } = this.props;
+ const { center, zoom, mapsConfig } = this.props;
const { lat, lng } = center;
const position = [lng, lat];
@@ -110,7 +106,7 @@ class DynamicMapboxMap extends Component {
}
// fuzzy circle change
- if (coordinatesConfig.fuzzy && centerChanged) {
+ if (mapsConfig.fuzzy.enabled && centerChanged) {
if (this.map.loaded()) {
this.updateFuzzyCirclelayer();
} else {
@@ -118,14 +114,14 @@ class DynamicMapboxMap extends Component {
}
}
- // NOTE: coordinatesConfig changes are not handled
+ // NOTE: mapsConfig changes are not handled
}
updateFuzzyCirclelayer() {
if (!this.map) {
// map already removed
return;
}
- const { center, coordinatesConfig } = this.props;
+ const { center, mapsConfig } = this.props;
const { lat, lng } = center;
const position = [lng, lat];
@@ -133,7 +129,7 @@ class DynamicMapboxMap extends Component {
// We have to use a different layer id to avoid Mapbox errors
this.fuzzyLayerId = generateFuzzyLayerId();
- this.map.addLayer(circleLayer(center, coordinatesConfig, this.fuzzyLayerId));
+ this.map.addLayer(circleLayer(center, mapsConfig, this.fuzzyLayerId));
this.map.setCenter(position);
}
@@ -150,8 +146,8 @@ class DynamicMapboxMap extends Component {
DynamicMapboxMap.defaultProps = {
address: '',
center: null,
- zoom: config.coordinates.fuzzy ? config.coordinates.fuzzyDefaultZoomLevel : 11,
- coordinatesConfig: config.coordinates,
+ zoom: config.maps.fuzzy.enabled ? config.maps.fuzzy.defaultZoomLevel : 11,
+ mapsConfig: config.maps,
};
DynamicMapboxMap.propTypes = {
@@ -161,7 +157,7 @@ DynamicMapboxMap.propTypes = {
lng: number.isRequired,
}).isRequired,
zoom: number,
- coordinatesConfig: object,
+ mapsConfig: object,
};
export default DynamicMapboxMap;
diff --git a/src/components/Map/Map.example.js b/src/components/Map/Map.example.js
index 82c155e5..f2d24e74 100644
--- a/src/components/Map/Map.example.js
+++ b/src/components/Map/Map.example.js
@@ -31,9 +31,12 @@ export const WithObfuscatedLocation = {
obfuscatedCenter: new LatLng(60.16502999999999, 24.940064399999983),
address: 'Sharetribe',
zoom: 14,
- coordinatesConfig: {
- ...config.coordinates,
- fuzzy: true,
+ mapsConfig: {
+ ...config.maps,
+ fuzzy: {
+ ...config.maps.fuzzy,
+ enabled: true,
+ },
},
},
};
@@ -48,9 +51,12 @@ export const WithCircleLocation = {
center: new LatLng(60.16502999999999, 24.940064399999983),
obfuscatedCenter: obfuscatedCoordinates(new LatLng(60.16502999999999, 24.940064399999983)),
address: 'Sharetribe',
- coordinatesConfig: {
- ...config.coordinates,
- fuzzy: true,
+ mapsConfig: {
+ ...config.maps,
+ fuzzy: {
+ ...config.maps.fuzzy,
+ enabled: true,
+ },
},
},
};
diff --git a/src/components/Map/Map.js b/src/components/Map/Map.js
index e769252d..91012122 100644
--- a/src/components/Map/Map.js
+++ b/src/components/Map/Map.js
@@ -18,32 +18,27 @@ export class Map extends Component {
center,
obfuscatedCenter,
zoom,
- coordinatesConfig,
+ mapsConfig,
useStaticMap,
} = this.props;
const classes = classNames(rootClassName || css.root, className);
const mapClasses = mapRootClassName || css.mapRoot;
- if (coordinatesConfig.fuzzy && !obfuscatedCenter) {
+ if (mapsConfig.fuzzy.enabled && !obfuscatedCenter) {
throw new Error(
- 'Map: obfuscatedCenter prop is required when config.coordinates.fuzzy === true'
+ 'Map: obfuscatedCenter prop is required when config.maps.fuzzy.enabled === true'
);
}
- if (!coordinatesConfig.fuzzy && !center) {
- throw new Error('Map: center prop is required when config.coordinates.fuzzy === false');
+ if (!mapsConfig.fuzzy.enabled && !center) {
+ throw new Error('Map: center prop is required when config.maps.fuzzy.enabled === false');
}
- const location = coordinatesConfig.fuzzy ? obfuscatedCenter : center;
+ const location = mapsConfig.fuzzy.enabled ? obfuscatedCenter : center;
return !isMapsLibLoaded() ? (
) : useStaticMap ? (
-
+
) : (
}
@@ -53,7 +48,7 @@ export class Map extends Component {
center={location}
zoom={zoom}
address={address}
- coordinatesConfig={coordinatesConfig}
+ mapsConfig={mapsConfig}
/>
);
}
@@ -64,8 +59,8 @@ Map.defaultProps = {
rootClassName: null,
mapRootClassName: null,
address: '',
- zoom: config.coordinates.fuzzy ? config.coordinates.fuzzyDefaultZoomLevel : 11,
- coordinatesConfig: config.coordinates,
+ zoom: config.maps.fuzzy.enabled ? config.maps.fuzzy.defaultZoomLevel : 11,
+ mapsConfig: config.maps,
useStaticMap: false,
};
@@ -77,7 +72,7 @@ Map.propTypes = {
center: propTypes.latlng,
obfuscatedCenter: propTypes.latlng,
zoom: number,
- coordinatesConfig: object,
+ mapsConfig: object,
useStaticMap: bool,
};
diff --git a/src/components/Map/StaticGoogleMap.js b/src/components/Map/StaticGoogleMap.js
index a35285e2..3be7576c 100644
--- a/src/components/Map/StaticGoogleMap.js
+++ b/src/components/Map/StaticGoogleMap.js
@@ -34,21 +34,17 @@ const convertOpacity = opacity => {
};
// Draw a circle polyline for fuzzy location.
-const drawFuzzyCircle = (coordinatesConfig, center) => {
- if (
- !(
- coordinatesConfig &&
- typeof coordinatesConfig === 'object' &&
- center &&
- typeof center === 'object'
- )
- ) {
+const drawFuzzyCircle = (mapsConfig, center) => {
+ if (!(mapsConfig && typeof mapsConfig === 'object' && center && typeof center === 'object')) {
return '';
}
- const { fillColor, fillOpacity, strokeColor, strokeWeight } = coordinatesConfig.circleOptions;
+ const fillColor = mapsConfig.fuzzy.circleColor;
+ const fillOpacity = 0.2;
+ const strokeColor = mapsConfig.fuzzy.circleColor;
+ const strokeWeight = 1;
- const circleRadius = coordinatesConfig.coordinateOffset || 500;
+ const circleRadius = mapsConfig.fuzzy.offset || 500;
const circleStrokeWeight = strokeWeight || 1;
const circleStrokeColor = formatColorFromString(strokeColor);
const circleStrokeOpacity = convertOpacity(DEFAULT_STROKE_OPACITY);
@@ -70,8 +66,8 @@ const drawFuzzyCircle = (coordinatesConfig, center) => {
// Get custom marker data for static map URI
const customMarker = (options, lat, lng) => {
- const { anchorX, anchorY, markerURI } = options;
- return [`anchor:${anchorX},${anchorY}`, `icon:${markerURI}`, `${lat},${lng}`].join('|');
+ const { anchorX, anchorY, url } = options;
+ return [`anchor:${anchorX},${anchorY}`, `icon:${url}`, `${lat},${lng}`].join('|');
};
class StaticGoogleMap extends Component {
@@ -84,7 +80,7 @@ class StaticGoogleMap extends Component {
}
render() {
- const { center, zoom, address, coordinatesConfig, dimensions } = this.props;
+ const { center, zoom, address, mapsConfig, dimensions } = this.props;
const { lat, lng } = center || {};
const { width, height } = dimensions;
@@ -92,10 +88,10 @@ class StaticGoogleMap extends Component {
// 1. if fuzzy coordinates are used, return circle path
// 2. if customMarker is defined in config.js, use that
// 3. else return default marker
- const targetMaybe = coordinatesConfig.fuzzy
- ? { path: drawFuzzyCircle(coordinatesConfig, center) }
- : coordinatesConfig.customMarker
- ? { markers: customMarker(coordinatesConfig.customMarker, lat, lng) }
+ const targetMaybe = mapsConfig.fuzzy.enabled
+ ? { path: drawFuzzyCircle(mapsConfig, center) }
+ : mapsConfig.customMarker.enabled
+ ? { markers: customMarker(mapsConfig.customMarker, lat, lng) }
: { markers: `${lat},${lng}` };
const srcParams = stringify({
@@ -103,7 +99,7 @@ class StaticGoogleMap extends Component {
zoom,
size: `${width}x${height}`,
maptype: 'roadmap',
- key: config.googleMapsAPIKey,
+ key: config.maps.googleMapsAPIKey,
...targetMaybe,
});
@@ -118,8 +114,8 @@ StaticGoogleMap.defaultProps = {
rootClassName: null,
address: '',
center: null,
- zoom: config.coordinates.fuzzy ? config.coordinates.fuzzyDefaultZoomLevel : 11,
- coordinatesConfig: config.coordinates,
+ zoom: config.maps.fuzzy.enabled ? config.maps.fuzzy.defaultZoomLevel : 11,
+ mapsConfig: config.maps,
};
StaticGoogleMap.propTypes = {
@@ -131,7 +127,7 @@ StaticGoogleMap.propTypes = {
lng: number.isRequired,
}).isRequired,
zoom: number,
- coordinatesConfig: object,
+ mapsConfig: object,
// from withDimensions
dimensions: shape({
diff --git a/src/components/Map/StaticMapboxMap.js b/src/components/Map/StaticMapboxMap.js
index 2860e1e0..695e682e 100644
--- a/src/components/Map/StaticMapboxMap.js
+++ b/src/components/Map/StaticMapboxMap.js
@@ -9,42 +9,41 @@ const formatColor = color => {
return color.replace(/^#/, '');
};
-const fuzzyCircleOverlay = (center, coordinatesConfig) => {
- const {
- strokeWeight,
- strokeColor,
- strokeOpacity,
- fillColor,
- fillOpacity,
- } = coordinatesConfig.circleOptions;
- const path = circlePolyline(center, coordinatesConfig.coordinateOffset);
+const fuzzyCircleOverlay = (center, mapsConfig) => {
+ const strokeWeight = 1;
+ const strokeColor = mapsConfig.fuzzy.circleColor;
+ const strokeOpacity = 0.5;
+ const fillColor = mapsConfig.fuzzy.circleColor;
+ const fillOpacity = 0.2;
+
+ const path = circlePolyline(center, mapsConfig.fuzzy.offset);
const styles = `-${strokeWeight}+${formatColor(strokeColor)}-${strokeOpacity}+${formatColor(
fillColor
)}-${fillOpacity}`;
return `path${styles}(${encodeURIComponent(polyline.encode(path))})`;
};
-const customMarkerOverlay = (center, coordinatesConfig) => {
- const { markerURI } = coordinatesConfig.customMarker;
- return `url-${encodeURIComponent(markerURI)}(${center.lng},${center.lat})`;
+const customMarkerOverlay = (center, mapsConfig) => {
+ const { url } = mapsConfig.customMarker;
+ return `url-${encodeURIComponent(url)}(${center.lng},${center.lat})`;
};
const markerOverlay = center => {
return `pin-s(${center.lng},${center.lat})`;
};
-const mapOverlay = (center, coordinatesConfig) => {
- if (coordinatesConfig.fuzzy) {
- return fuzzyCircleOverlay(center, coordinatesConfig);
+const mapOverlay = (center, mapsConfig) => {
+ if (mapsConfig.fuzzy.enabled) {
+ return fuzzyCircleOverlay(center, mapsConfig);
}
- if (coordinatesConfig.customMarker) {
- return customMarkerOverlay(center, coordinatesConfig);
+ if (mapsConfig.customMarker.enabled) {
+ return customMarkerOverlay(center, mapsConfig);
}
return markerOverlay(center);
};
const StaticMapboxMap = props => {
- const { address, center, zoom, coordinatesConfig, dimensions } = props;
+ const { address, center, zoom, mapsConfig, dimensions } = props;
const { width, height } = dimensions;
const libLoaded = typeof window !== 'undefined' && window.mapboxgl;
@@ -52,13 +51,13 @@ const StaticMapboxMap = props => {
return null;
}
- const overlay = mapOverlay(center, coordinatesConfig);
+ const overlay = mapOverlay(center, mapsConfig);
const src =
'https://api.mapbox.com/styles/v1/mapbox/streets-v10/static' +
(overlay ? `/${overlay}` : '') +
`/${center.lng},${center.lat},${zoom}` +
`/${width}x${height}` +
- `?access_token=${window.mapboxgl.accessToken}`;
+ `?access_token=${config.maps.mapboxAccessToken}`;
return
;
};
@@ -66,8 +65,8 @@ const StaticMapboxMap = props => {
StaticMapboxMap.defaultProps = {
address: '',
center: null,
- zoom: config.coordinates.fuzzy ? config.coordinates.fuzzyDefaultZoomLevel : 11,
- coordinatesConfig: config.coordinates,
+ zoom: config.maps.fuzzy.enabled ? config.maps.fuzzy.defaultZoomLevel : 11,
+ mapsConfig: config.maps,
};
StaticMapboxMap.propTypes = {
@@ -77,7 +76,7 @@ StaticMapboxMap.propTypes = {
lng: number.isRequired,
}).isRequired,
zoom: number,
- coordinatesConfig: object,
+ mapsConfig: object,
// from withDimensions
dimensions: shape({
diff --git a/src/components/SearchMap/SearchMap.js b/src/components/SearchMap/SearchMap.js
index 66515b99..db100728 100644
--- a/src/components/SearchMap/SearchMap.js
+++ b/src/components/SearchMap/SearchMap.js
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
-import { arrayOf, bool, func, number, string, shape } from 'prop-types';
+import { arrayOf, bool, func, number, string, shape, object } from 'prop-types';
import { withRouter } from 'react-router-dom';
import { withGoogleMap, GoogleMap } from 'react-google-maps';
import classNames from 'classnames';
@@ -279,14 +279,14 @@ export class SearchMapComponent extends Component {
onCloseAsModal,
onIdle,
zoom,
- coordinatesConfig,
+ mapsConfig,
activeListingId,
} = this.props;
const classes = classNames(rootClassName || css.root, className);
const mapClasses = mapRootClassName || css.mapRoot;
const listingsWithLocation = originalListings.filter(l => !!l.attributes.geolocation);
- const listings = coordinatesConfig.fuzzy
+ const listings = mapsConfig.fuzzy.enabled
? withCoordinatesObfuscated(listingsWithLocation)
: listingsWithLocation;
const infoCardOpen = this.state.infoCardOpen;
@@ -345,7 +345,7 @@ SearchMapComponent.defaultProps = {
onCloseAsModal: null,
useLocationSearchBounds: true,
zoom: 11,
- coordinatesConfig: config.coordinates,
+ mapsConfig: config.maps,
};
SearchMapComponent.propTypes = {
@@ -361,9 +361,7 @@ SearchMapComponent.propTypes = {
onIdle: func.isRequired,
useLocationSearchBounds: bool, // eslint-disable-line react/no-unused-prop-types
zoom: number,
- coordinatesConfig: shape({
- fuzzy: bool.isRequired,
- }),
+ mapsConfig: object,
// from withRouter
history: shape({
diff --git a/src/config.js b/src/config.js
index 054e7c14..fcee6962 100644
--- a/src/config.js
+++ b/src/config.js
@@ -1,4 +1,5 @@
import * as custom from './marketplace-custom-config.js';
+import defaultLocationSearches from './default-location-searches';
const env = process.env.REACT_APP_ENV;
const dev = process.env.REACT_APP_ENV === 'development';
@@ -262,57 +263,74 @@ const siteFacebookPage = 'https://www.facebook.com/Sharetribe/';
// You should create one to track social sharing in Facebook
const facebookAppId = null;
-// Google Maps API key is needed for static map images.
-const googleMapsAPIKey = process.env.REACT_APP_GOOGLE_MAPS_API_KEY;
+const maps = {
+ mapboxAccessToken: process.env.REACT_APP_MAPBOX_ACCESS_TOKEN,
+ googleMapsAPIKey: process.env.REACT_APP_GOOGLE_MAPS_API_KEY,
-const coordinates = {
- // If true, obfuscate the coordinates of the listings that are shown
- // on a map.
- fuzzy: false,
+ // The location search input can be configured to show default
+ // searches when the user focuses on the input and hasn't yet typed
+ // anything. This reduces typing and avoids too many Geolocation API
+ // calls for common searches.
+ search: {
+ // When enabled, the first suggestion is "Current location" that
+ // uses the browser Geolocation API to query the user's current
+ // location.
+ suggestCurrentLocation: process.env.REACT_APP_DEFAULT_SEARCHES_ENABLED === 'true',
- // Default zoom level when showing a single circle on a Map. Should
- // be small enough so the whole circle fits in.
- fuzzyDefaultZoomLevel: 14,
+ // Distance in meters for calculating the bounding box around the
+ // current location.
+ currentLocationBoundsDistance: 1000,
- // When fuzzy === true, the coordinates on the Map component are
- // obfuscated and a circle is shown instead of a marker. To decide a
- // proper value for the offset and the radius, see:
- //
- // https://gis.stackexchange.com/a/8674
-
- // Amount of maximum offset in meters that is applied to obfuscate
- // the original coordinates. The actual value is random, but the
- // obfuscated coordinates are withing a circle that has the same
- // radius as the offset.
- coordinateOffset: 500,
-
- // Options to style the circle appearance.
- //
- // See: https://developers.google.com/maps/documentation/javascript/reference#CircleOptions
- circleOptions: {
- fillColor: '#c0392b',
- fillOpacity: 0.2,
- strokeColor: '#c0392b',
- strokeOpacity: 0.5,
- strokeWeight: 1,
- clickable: false,
+ // Example location can be edited in the
+ // `default-location-searches.js` file.
+ defaults: defaultLocationSearches,
},
- // An option to use custom marker on static maps. Uncomment to enable it.
- // https://developers.google.com/maps/documentation/maps-static/dev-guide#Markers
+ // When fuzzy locations are enabled, coordinates on maps are
+ // obfuscated randomly around the actual location.
//
- // Note 1: fuzzy coordinate circle overwrites these custom marker settings)
- // Note 2: markerURI needs to be a public URI accessible by Google Maps API servers.
- // The easiest place is /public/static/icons/ folder, but then the marker image is not available
- // while developing through localhost.
+ // NOTE: This only hides the locations in the UI level, the actual
+ // coordinates are still accessible in the HTTP requests and the
+ // Redux store.
+ fuzzy: {
+ enabled: false,
- // customMarker: {
- // markerURI: encodeURI(`${canonicalRootURL}/static/icons/map-marker-32x32.png`),
- // anchorX: 16,
- // anchorY: 32,
- // width: 32,
- // height: 32,
- // },
+ // Amount of maximum offset in meters that is applied to obfuscate
+ // the original coordinates. The actual value is random, but the
+ // obfuscated coordinates are withing a circle that has the same
+ // radius as the offset.
+ offset: 500,
+
+ // Default zoom level when showing a single circle on a Map. Should
+ // be small enough so the whole circle fits in.
+ defaultZoomLevel: 13,
+
+ // Color of the circle on the Map component.
+ circleColor: '#c0392b',
+ },
+
+ // Custom marker image to use in the Map component.
+ //
+ // NOTE: Not used if fuzzy locations are enabled.
+ customMarker: {
+ enabled: false,
+
+ // Publicly accessible URL for the custom marker image.
+ //
+ // The easiest place is /public/static/icons/ folder, but then the
+ // marker image is not available while developing through
+ // localhost.
+ url: encodeURI(`${canonicalRootURL}/static/icons/map-marker-32x32.png`),
+
+ // Dimensions of the marker image.
+ width: 32,
+ height: 32,
+
+ // Position to anchor the image in relation to the coordinates,
+ // ignored when using Mapbox.
+ anchorX: 16,
+ anchorY: 32,
+ },
};
// NOTE: only expose configuration that should be visible in the
@@ -350,8 +368,7 @@ const config = {
facebookAppId,
sentryDsn,
usingSSL,
- googleMapsAPIKey,
- coordinates,
+ maps,
custom,
};
diff --git a/src/containers/ListingPage/SectionMapMaybe.js b/src/containers/ListingPage/SectionMapMaybe.js
index 521d5ff9..a6d0127c 100644
--- a/src/containers/ListingPage/SectionMapMaybe.js
+++ b/src/containers/ListingPage/SectionMapMaybe.js
@@ -25,7 +25,7 @@ class SectionMapMaybe extends Component {
const address = publicData.location ? publicData.location.address : '';
const classes = classNames(rootClassName || css.sectionMap, className);
- const mapProps = config.coordinates.fuzzy
+ const mapProps = config.maps.fuzzy.enabled
? { obfuscatedCenter: obfuscatedCoordinates(geolocation, listingId ? listingId.uuid : null) }
: { address, center: geolocation };
const map = ;
diff --git a/src/default-location-searches.js b/src/default-location-searches.js
new file mode 100644
index 00000000..e83c37ba
--- /dev/null
+++ b/src/default-location-searches.js
@@ -0,0 +1,51 @@
+import { types as sdkTypes } from './util/sdkLoader';
+
+const { LatLng, LatLngBounds } = sdkTypes;
+
+// An array of locations to show in the LocationAutocompleteInput when
+// the input is in focus but the user hasn't typed in any search yet.
+//
+// Each item in the array should be an object with a unique `id` (String) and a
+// `predictionPlace` (util.types.place) properties.
+export default [
+ {
+ id: 'default-helsinki',
+ predictionPlace: {
+ address: 'Helsinki, Finland',
+ origin: new LatLng(60.16985, 24.93837),
+ bounds: new LatLngBounds(new LatLng(60.29783, 25.25448), new LatLng(59.92248, 24.78287)),
+ },
+ },
+ {
+ id: 'default-turku',
+ predictionPlace: {
+ address: 'Turku, Finland',
+ origin: new LatLng(60.45181, 22.26663),
+ bounds: new LatLngBounds(new LatLng(60.53045, 22.38197), new LatLng(60.33361, 22.06644)),
+ },
+ },
+ {
+ id: 'default-tampere',
+ predictionPlace: {
+ address: 'Tampere, Finland',
+ origin: new LatLng(61.49775, 23.76095),
+ bounds: new LatLngBounds(new LatLng(61.83657, 24.11838), new LatLng(61.42728, 23.5422)),
+ },
+ },
+ {
+ id: 'default-oulu',
+ predictionPlace: {
+ address: 'Oulu, Finland',
+ origin: new LatLng(65.01208, 25.46507),
+ bounds: new LatLngBounds(new LatLng(65.56434, 26.77069), new LatLng(64.8443, 24.11494)),
+ },
+ },
+ {
+ id: 'default-ruka',
+ predictionPlace: {
+ address: 'Ruka, Finland',
+ origin: new LatLng(66.16546, 29.15172),
+ bounds: new LatLngBounds(new LatLng(66.16997, 29.16773), new LatLng(66.16095, 29.13572)),
+ },
+ },
+];
diff --git a/src/util/maps.js b/src/util/maps.js
index efcf4672..b3f410e9 100644
--- a/src/util/maps.js
+++ b/src/util/maps.js
@@ -12,10 +12,9 @@ const { LatLng } = sdkTypes;
*/
const obfuscatedCoordinatesImpl = (latlng, cacheKey) => {
const { lat, lng } = latlng;
- const offset = config.coordinates.coordinateOffset;
// https://gis.stackexchange.com/questions/25877/generating-random-locations-nearby
- const r = offset / 111300;
+ const r = config.maps.fuzzy.offset / 111300;
const y0 = lat;
const x0 = lng;