Skip to content

Instantly share code, notes, and snippets.

@ghoshabhi
Last active June 13, 2017 20:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ghoshabhi/a275f923bba4a92b2b1f9dc3fbe09826 to your computer and use it in GitHub Desktop.
Save ghoshabhi/a275f923bba4a92b2b1f9dc3fbe09826 to your computer and use it in GitHub Desktop.
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import PropTypes from 'prop-types';
import Section from 'grommet/components/Section';
import Map from '../../components/Map';
import * as MapActionCreators from './actions';
// import icons from '../../assets/icons-util';
import { find, near } from '../FilterContainer/utils';
class MapContainer extends Component {
constructor(props) {
super(props);
this.state = {
markers: {},
map: null,
maps: null,
placeId: null,
usePagination: false,
useRadarSearch: false,
};
this.handleBoundsChange = this.handleBoundsChange.bind(this);
this.handleMapLoaded = this.handleMapLoaded.bind(this);
this.handleSearchResults = this.handleSearchResults.bind(this);
this.createMarker = this.createMarker.bind(this);
this.onMapMarkerClick = this.onMapMarkerClick.bind(this);
this.addMarker = this.addMarker.bind(this);
this.removeMarker = this.removeMarker.bind(this);
}
// componentDidUpdate(prevProps, prevState) {
// console.log(`
// PREV_PROPS: ${JSON.stringify(prevProps)},
// PREV_STATE: ${JSON.stringify(prevState)};
// `);
// }
// componentWillReceiveProps() {
// console.log(
// `THIS_PROPS_MAP: ${JSON.stringify(this.props.selectedFilters)}`,
// );
// }
// componentWillUpdate(nextProps) {
// console.log(`
// NEXT_PROPS: ${JSON.stringify(nextProps)}
// `);
// }
componentWillReceiveProps(nextProps) {
console.log(`NEXT_PROPS_MAP: ${JSON.stringify(nextProps.selectedFilters)}`);
console.log(
`THIS_PROPS_MAP: ${JSON.stringify(this.props.selectedFilters)}`,
);
const thisSet = new Set(this.props.selectedFilters);
const nextSet = new Set(nextProps.selectedFilters);
thisSet.forEach(filterKey => {
if (!nextSet.has(filterKey)) {
this.removeMarkers(this.state.map, this.state.maps, filterKey);
}
});
// check for added filters
nextSet.forEach(filterKey => {
if (!thisSet.has(filterKey)) {
this.addMarkers(this.state.map, this.state.maps, filterKey);
}
});
}
onMapMarkerClick(placeId) {
console.log(`PLACE_ID: ${placeId}`);
this.setState({ placeId });
}
findFilter = filterKey => {
let filterFound = null;
const obj =
find.find(o => o.name === filterKey) ||
near.find(o => o.name === filterKey);
if (obj) {
filterFound = obj;
}
return filterFound;
};
createMarker(place, filterKey) {
const { map, maps } = this.state;
const infoWindow = new maps.InfoWindow();
const filterObj = this.findFilter(filterKey);
const position = place.geometry.location;
const marker = new maps.Marker({
map,
icon: filterObj && filterObj.svgComp,
position,
});
// Click event for Marker
maps.event.addListener(marker, 'click', () => {
this.onMapMarkerClick(place.place_id);
});
// Mouseover event for Marker
maps.event.addListener(marker, 'mouseover', () => {
const content = `
<div>
<span style='font-height: bold'>${place.name}</span>
</div>
<div>
Rating: ${place.rating ? `${place.rating}/5` : 'unknown'}
</div>
<div>
Price: ${place.price_level ? place.price_level : 'unknown'}
</div>
`;
infoWindow.setContent(content);
infoWindow.open(map, this);
});
}
handleSearchResults(results, status, pagination, filterKey) {
const { map, maps, usePagination } = this.state;
if (maps && maps.places.PlacesServiceStatus.OK) {
const markers = [];
for (let i = 0; i < results.length; i++) {
const marker = this.createMarker(results[i], filterKey);
markers.push(marker);
}
const markerWithKey = this.state.markers;
markerWithKey[filterKey] = markers;
this.setState({ markers: markerWithKey });
if (usePagination && pagination && pagination.hasNextPage) {
pagination.nextPage();
} else {
document.body.style.cursor = 'auto';
map.setOptions({ draggableCursor: 'auto' });
}
}
}
addMarker(map, maps, filterKey) {
const service = new maps.places.PlacesService(map);
const filterObj = this.findFilter(filterKey);
const isPlaceSearch = filterObj && filterObj.searchType === 'place';
const bounds = map.getBounds();
map.setOptions({ draggableCursor: 'wait' });
if (this.state.useRadarSearch) {
const request = {
bounds,
name: filterKey,
};
service.radarSearch(request, this.handleSearchResults);
} else if (isPlaceSearch) {
const request = {
bounds,
type: filterKey.toLowerCase(),
};
service.nearbySearch(request, this.handleSearchResults);
} else {
const request = {
bounds,
query: filterKey,
};
service.textSearch(request, this.handleSearchResults);
}
}
removeMarker(map, maps, filterKey) {
const markersInState = this.state.markers;
markersInState[filterKey].forEach(marker => marker.setMap(null));
markersInState[filterKey] = [];
this.setState({ markers: markersInState });
}
handleMapLoaded(map, maps) {
this.setState({ map, maps });
}
handleBoundsChange(center, zoom) {
const { actions } = this.props;
console.log(
`handleBoundsChange called: ${center.lat} ${center.lng} ${zoom}`,
);
actions.setMapCenter(center);
actions.setMapZoomLevel(zoom);
}
render() {
const { center, zoom, selectedFilters } = this.props;
console.log(`SELECTED_FILTERS: ${selectedFilters}`);
return (
<Section pad="none">
<Map
center={center}
zoom={zoom}
onMapLoaded={(map, maps) => this.handleMapLoaded(map, maps)}
onBoundsChange={this.handleBoundsChange}
/>
</Section>
);
}
}
MapContainer.propTypes = {
actions: PropTypes.func.isRequired,
center: PropTypes.shape({
lat: PropTypes.number.isRequired,
lng: PropTypes.number.isRequired,
}).isRequired,
zoom: PropTypes.number.isRequired,
selectedFilters: PropTypes.arrayOf(PropTypes.string).isRequired,
};
const mapStateToProps = state => ({
center: state.mapContainer.center,
zoom: state.mapContainer.zoom,
selectedFilters: state.filterListContainer.selectedFilters,
});
const mapDispatchToProps = dispatch => ({
actions: bindActionCreators(MapActionCreators, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(MapContainer);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment