Skip to content

Commit a06cee3

Browse files
committed
map reworked to handle arbitrary pin locations and new google maps version
1 parent 5dbf08a commit a06cee3

File tree

5 files changed

+126
-45
lines changed

5 files changed

+126
-45
lines changed

App.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React, { Component } from "react";
22
import { Route, Switch } from "react-router-dom";
3-
// import GoogleMap from "./GoogleMap";
43
import Map from './components/maps/Map';
54
import Login from "./Login";
65
import Sidebar from "./Sidebar";

components/GoogleApi.jsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
import React from 'react'
2-
import { GoogleApiWrapper } from 'google-maps-react'
32
import createContext from 'create-react-context'
43

54
const ApiContext = createContext(null)
65

7-
export const GoogleProvider = GoogleApiWrapper({
8-
apiKey: "AIzaSyBNO9SHxnyzMG6J1FCDYcle7DjXMjg6jBU"
9-
})(
10-
({google, children}) =>
11-
<ApiContext.Provider value={google}>{
6+
export class GoogleProvider extends React.PureComponent {
7+
async componentDidMount() {
8+
await window.__googleHasLoaded__
9+
this.setState({loaded: true})
10+
}
11+
12+
render() {
13+
if (!window.google) return null
14+
const {children} = this.props
15+
return <ApiContext.Provider value={window.google}>{
1216
children
1317
}</ApiContext.Provider>
14-
)
18+
}
19+
}
1520

1621
export default ApiContext.Consumer

components/MapView.jsx

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react'
2-
import GoogleMap, {Marker} from './maps/Map'
2+
import GoogleMap, {Marker, Info} from './maps/Map'
33
import {Map} from 'fireview'
44
import firebase from '~/fire'
55
import debounce from 'debounce'
@@ -35,32 +35,61 @@ const writeTags = debounce(
3535

3636
const TagInput = ({ from, style }) =>
3737
<Map from={from}
38-
Render={
39-
({ tags }) =>
40-
<input
41-
style={style}
42-
defaultValue={tagsAsString(tags)}
43-
onChange={setTags(from)} />
44-
} />
38+
Render={
39+
({ tags }) =>
40+
<input
41+
style={style}
42+
defaultValue={tagsAsString(tags)}
43+
onChange={setTags(from)} />
44+
} />
45+
46+
47+
export default class Editor extends React.Component {
48+
state = {adding: null}
49+
50+
mapWasClicked = ({latLng}) =>
51+
this.setState({adding: latLng})
52+
53+
addPlace = latLng => evt => {
54+
evt.preventDefault()
55+
return this.props.of.collection('places').add({
56+
position: new GeoPoint(latLng.lat(), latLng.lng()),
57+
name: evt.target.name.value
58+
}).then(() => this.setState({adding: null}))
59+
}
60+
61+
get addPlaceWindow() {
62+
const {adding} = this.state
63+
if (!adding) return null
64+
return (
65+
<Info position={adding}>
66+
<form onSubmit={this.addPlace(adding)}>
67+
<input name="name" />
68+
<input type="submit" value="➕" />
69+
</form>
70+
</Info>
71+
)
72+
}
73+
74+
render() {
75+
const {of} = this.props
4576

46-
export default ({ of }) => <div style={{position: 'relative'}}>
47-
<GoogleMap
48-
onClick={
49-
({latLng}) =>
50-
of.collection('places').add({
51-
position: new GeoPoint(latLng.lat(), latLng.lng())
52-
})
53-
}
54-
defaultCenter={{lat: 40.732540, lng: -74.005120}}
55-
defaultZoom={10}>
56-
<Layer map={of} />
57-
</GoogleMap>
58-
<TagInput
59-
from={of}
60-
style={{
61-
top: '9px',
62-
right: '9px',
63-
position: 'absolute',
64-
zIndex: 500000,
65-
}} />
66-
</div>
77+
return <div style={{position: 'relative'}}>
78+
<GoogleMap
79+
onClick={this.mapWasClicked}
80+
defaultCenter={{lat: 40.732540, lng: -74.005120}}
81+
defaultZoom={10}>
82+
<Layer map={of} />
83+
{this.addPlaceWindow}
84+
</GoogleMap>
85+
<TagInput
86+
from={of}
87+
style={{
88+
top: '9px',
89+
right: '9px',
90+
position: 'absolute',
91+
zIndex: 500000,
92+
}} />
93+
</div>
94+
}
95+
}

components/maps/Map.jsx

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,18 @@ const db = firebase.firestore();
1717

1818
const { Provider, Consumer } = createReactContext(null)
1919

20+
export const MapConsumer = Consumer
21+
2022
export const Marker = props =>
2123
<Consumer>{
2224
map => map && <RenderMarker map={map} {...props} />
2325
}</Consumer>
2426

27+
export const Info = props =>
28+
<Consumer>{
29+
map => map && <RenderInfoWindow map={map} {...props} />
30+
}</Consumer>
31+
2532
class RenderMarker extends Component {
2633
componentDidMount() {
2734
this.marker = new google.maps.Marker(this.props)
@@ -36,30 +43,65 @@ class RenderMarker extends Component {
3643
}
3744
}
3845

39-
class GoogleMap extends Component {
46+
class RenderInfoWindow extends Component {
47+
node = document.createElement('div')
48+
4049
componentDidMount() {
41-
this.loadMap(this.props);
50+
this.win = new google.maps.InfoWindow({
51+
content: this.node,
52+
...this.props,
53+
})
54+
this.win.addListener('close', console.log)
4255
}
4356

4457
componentWillReceiveProps(props) {
45-
this.loadMap(props);
58+
if (props.position !== this.props.position)
59+
this.win.setPosition(props.position)
4660
}
4761

48-
loadMap({ google, onClick }) {
62+
componentWillUnmount() {
63+
this.win.close()
64+
}
65+
66+
render() {
67+
return ReactDOM.createPortal(this.props.children, this.node)
68+
}
69+
}
70+
71+
class GoogleMap extends React.PureComponent {
72+
componentDidMount() {
73+
this.setup(this.props);
74+
}
75+
76+
componentWillReceiveProps(props) {
77+
this.setup(props);
78+
}
79+
80+
setup({ google, onClick }) {
4981
if (!google) return;
5082

83+
const map = this.initMap(google)
84+
85+
onClick && map.addListener('click', onClick)
86+
}
87+
88+
initMap(google) {
89+
if (this.map) return this.map
90+
5191
const maps = google.maps;
5292
const node = this.refs.map;
5393

5494
const map = new maps.Map(node,
5595
{
5696
center: this.props.defaultCenter,
5797
zoom: this.props.defaultZoom,
58-
mapTypeId: "roadmap"
98+
mapTypeId: this.props.defaultType || "roadmap"
5999
});
60100

61-
onClick && map.addListener('click', onClick)
101+
this.map = map
62102
this.setState({map})
103+
104+
return map
63105
}
64106

65107
render() {

public/index.html

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@
44
<link rel="stylesheet" href="/main.css">
55
</head>
66
<body>
7-
<div id="main" />
8-
<script async defer src="/bundle.js"></script>
7+
<div id="main"></div>
8+
<script>
9+
window.__googleHasLoaded__ = new Promise(resolve =>
10+
window.__initGoogleMap__ = resolve)
11+
</script>
12+
<script async defer src="/bundle.js"></script>
13+
<script
14+
src="https://maps.googleapis.com/maps/api/js?v=3.exp&key=AIzaSyBNO9SHxnyzMG6J1FCDYcle7DjXMjg6jBU&callback=__initGoogleMap__"></script>
915
</body>
1016
</html>

0 commit comments

Comments
 (0)