From cd047f0606b9b885b5a5980aba8f018d9f949282 Mon Sep 17 00:00:00 2001
From: Aubrey-Li <63608597+Aubrey-Li@users.noreply.github.com>
Date: Sat, 24 Jul 2021 13:57:37 -0700
Subject: bug fixes with info window

---
 .../collections/MapView/CollectionMapView.tsx      | 261 +++++++--------------
 1 file changed, 85 insertions(+), 176 deletions(-)

(limited to 'src/client/views/collections/MapView/CollectionMapView.tsx')

diff --git a/src/client/views/collections/MapView/CollectionMapView.tsx b/src/client/views/collections/MapView/CollectionMapView.tsx
index 290972364..d7025f6da 100644
--- a/src/client/views/collections/MapView/CollectionMapView.tsx
+++ b/src/client/views/collections/MapView/CollectionMapView.tsx
@@ -31,9 +31,14 @@ import { MapMarker } from '../../nodes/MapMarker/MapMarker';
 type MapSchema = makeInterface<[typeof documentSchema]>;
 const MapSchema = makeInterface(documentSchema);
 
+export type Coordinates = {
+    lat: number,
+    lng: number,
+}
+
 export type LocationData = {
-    id?: number;
-    pos?: { lat: number, lng: number };
+    id: string;
+    pos: Coordinates;
 };
 
 const mapContainerStyle = {
@@ -45,6 +50,28 @@ const defaultCenter = {
     lng: -115.234,
 };
 
+const mapOptions = {
+    fullscreenControl: false,
+}
+
+const drawingManager = new google.maps.drawing.DrawingManager({
+    drawingControl: true,
+    drawingControlOptions: {
+        position: google.maps.ControlPosition.TOP_RIGHT,
+        drawingModes: [
+            google.maps.drawing.OverlayType.MARKER,
+            google.maps.drawing.OverlayType.CIRCLE,
+            google.maps.drawing.OverlayType.POLYLINE,
+        ],
+    },
+});
+
+const options = {
+    fields: ["formatted_address", "geometry", "name"], // note: level of details is charged by item per retrieval, not recommended to return all fields
+    strictBounds: false,
+    types: ["establishment"], // type pf places, subject of change according to user need
+} as google.maps.places.AutocompleteOptions;
+
 @observer
 export default class CollectionMapView extends CollectionSubView<MapSchema, Partial<GoogleMapProps>>(MapSchema) {
     private _dropDisposer?: DragManager.DragDropDisposer;
@@ -52,8 +79,8 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
 
 
     @observable private _map = null as unknown as google.maps.Map;
-    @observable private selectedPlace: LocationData = null as any;
-    @observable private markerMap = {};
+    @observable private selectedPlace: LocationData | undefined;
+    @observable private markerMap: { [id: string]: google.maps.Marker } = {};
     @observable private center = defaultCenter;
     @observable private zoom = 2.5;
     @observable private clickedLatLng = null;
@@ -62,19 +89,12 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
     @observable private inputRef = React.createRef<HTMLInputElement>();
     @observable private buttonRef = React.createRef<HTMLDivElement>();
     @observable private searchMarkers: google.maps.Marker[] = [];
+    @observable private searchBox = new window.google.maps.places.Autocomplete(this.inputRef.current!, options);
 
-    private options = {
-        fields: ["formatted_address", "geometry", "name"], // note: level of details is charged by item per retrieval, not recommended to return all fields
-        strictBounds: false,
-        types: ["establishment"], // type pf places, subject of change according to user need
-    } as google.maps.places.AutocompleteOptions;
-
-    @observable private searchBox = new window.google.maps.places.Autocomplete(this.inputRef.current!, this.options);
-
-    @observable private myPlaces = [
-        { id: 1, pos: { lat: 39.09366509575983, lng: -94.58751660204751 } },
-        { id: 2, pos: { lat: 41.82399, lng: -71.41283 } },
-        { id: 3, pos: { lat: 47.606214, lng: -122.33207 } },
+    @observable private myPlaces: LocationData[] = [
+        { id: "id1", pos: { lat: 39.09366509575983, lng: -94.58751660204751 } },
+        { id: "id2", pos: { lat: 41.82399, lng: -71.41283 } },
+        { id: "id3", pos: { lat: 47.606214, lng: -122.33207 } },
     ];
 
     @action
@@ -82,87 +102,46 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
         this.searchBox = searchBox;
     }
 
-    @action
-    private setButton = (button: any) => {
-        this.buttonRef = button;
-        this._map.controls[google.maps.ControlPosition.TOP_RIGHT].push(this.buttonRef.current!)
-    }
-
     // iterate myPlaces to size, center, and zoom map to contain all markers
     private fitBounds = (map: google.maps.Map) => {
         console.log('map bound is:' + this.bounds);
-        this.myPlaces.map(place => {
-            this.bounds.extend(place.pos);
-            return place.id;
-        });
-        map.fitBounds(this.bounds)
+        this.myPlaces ? this.myPlaces.map(place => {
+            this.bounds.extend(place.pos!);
+        }) : null;
+        map.fitBounds(this.bounds);
     }
 
     // store a reference to google map instance; fit map bounds to contain all markers
     @action
     private loadHandler = (map: google.maps.Map) => {
         this._map = map;
+        drawingManager.setMap(map);
         this.fitBounds(map);
-
-        // //add a custom control for button add marker 
-        // //TODO: why this doesn't work
-        // const google = window.google;
-        // console.log("google window: " + google)
-        // const controlButtonDiv = document.createElement('div');
-        // ReactDOM.render(<button onClick={() => console.log('click me to add marker!')}>Add Marker</button>, controlButtonDiv);
-        // map.controls[google.maps.ControlPosition.TOP_RIGHT].push(controlButtonDiv);
     }
 
     @action
-    private markerClickHandler = (e: MouseEvent, place: LocationData) => {
+    private markerClickHandler = (e: MouseEvent, place: any) => {
         // set which place was clicked
-        this.selectedPlace = place
+        this.selectedPlace = place;
 
-        console.log(this.selectedPlace.id);
-        console.log(this.selectedPlace.pos);
+        console.log(this.selectedPlace);
 
         // used so clicking a second marker works
         if (this.infoWindowOpen) {
             this.infoWindowOpen = false;
             console.log("closeinfowindow")
         }
-        else {
-            this.infoWindowOpen = true;
-            console.log("open infowindow")
-        }
+        this.infoWindowOpen = true;
+        console.log("open infowindow")
     }
 
-    // @action
-    // private handleInfoWindowClose = () => {
-    //     if (this.infoWindowOpen) {
-    //         this.infoWindowOpen = false;
-    //     }
-    //     this.infoWindowOpen = false;
-    //     this.selectedPlace = { id: undefined, pos: undefined };
-    // }
-
-    // @action 
-    // private markerLoadHandler = (marker: any, place: LocationData) => {
-    //     if (marker != null) {
-    //         this.markerMap[place.id] = marker;
-    //     }
-    // }
-
     @action
-    @undoBatch
-    private handleDragMarker = (marker: any, place: LocationData) => {
-        // if (marker != null) {
-        //     place = {
-        //         id: place.id,
-        //         position: {
-        //             lat: marker.latLng.lat().toFixed(3),
-        //             lng: marker.latLng.lng().toFixed(3)
-        //         }
-        //     }
-
-        //     console.log(place);
-        //     console.log(this.myPlaces);
-        // }
+    private handleInfoWindowClose = () => {
+        if (this.infoWindowOpen) {
+            this.infoWindowOpen = false;
+        }
+        this.infoWindowOpen = false;
+        this.selectedPlace = undefined;
     }
 
     @action
@@ -186,17 +165,16 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
             this._map.setZoom(17);
         }
 
-        /** 
-         * customize icon => customized icon for the nature of the location selected (hard to tell from other pre-existing markers, probably won't implement
-         */
-        // const icon = {
-        //     url: place.icon as string,
-        //     size: new google.maps.Size(71, 71),
-        //     origin: new google.maps.Point(0, 0),
-        //     anchor: new google.maps.Point(17, 34),
-        //     scaledSize: new google.maps.Size(25, 25),
-        // };
+        // customize icon => customized icon for the nature of the location selected
+        const icon = {
+            url: place.icon as string,
+            size: new google.maps.Size(71, 71),
+            origin: new google.maps.Point(0, 0),
+            anchor: new google.maps.Point(17, 34),
+            scaledSize: new google.maps.Size(25, 25),
+        };
 
+        // put temporary cutomized marker on searched location
         this.searchMarkers.forEach((marker) => {
             marker.setMap(null);
         });
@@ -204,64 +182,13 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
         this.searchMarkers.push(
             new window.google.maps.Marker({
                 map: this._map,
+                icon,
                 title: place.name,
                 position: place.geometry.location,
             })
         )
     }
 
-    // @computed get markerContent() {
-    //     const allMarkers = this.childLayoutPairs
-    //     const markerId = NumCast(this.layoutDoc._itemIndex);
-    //     const selectedMarker = this.childLayoutPairs?.[markerId];
-    //     const position = {
-    //         lat: NumCast(this.layoutDoc.lat),
-    //         lng: NumCast(this.layoutDoc.lng)
-    //     }
-    //     return <>
-    //         {
-    //             allMarkers?.map(place => (
-    //                 <Marker
-    //                     key={markerId}
-    //                     position={position}
-    //                     onClick={e => this.markerClickHandler(e, place.layout)} //??
-    //                     draggable={true}
-    //                     onDragEnd={marker => this.handleDragMarker(marker, place.layout)}
-    //                 />
-    //             ))
-    //         }
-    //         {this.infoWindowOpen && selectedMarker && (
-    //             <InfoBox
-    //                 //anchor={selectedMarker}
-    //                 // onCloseClick={this.handleInfoWindowClose}
-    //                 position={position}
-    //             // options={{ enableEventPropagation: true }}
-    //             >
-    //                 <div style={{ backgroundColor: 'white', opacity: 0.75, padding: 12 }}>
-    //                     <div style={{ fontSize: 16 }}>
-    //                         {/* the linkmenu as the ones in other nodes */}
-    //                         <div>
-    //                             <a>a link to another node</a>
-    //                             <hr />
-    //                         </div>
-    //                         <div>
-    //                             <a>a link to another node</a>
-    //                             <hr />
-    //                         </div>
-    //                         <div>
-    //                             <a>a link to another node</a>
-    //                             <hr />
-    //                         </div>
-    //                         <div>
-    //                             <button>New +</button>
-    //                         </div>
-    //                     </div>
-    //                 </div>
-    //             </InfoBox>
-    //         )}
-
-    //     </>
-    // }
 
     @action
     private addMarker = (location: google.maps.LatLng | undefined, map: google.maps.Map) => {
@@ -271,18 +198,10 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
         });
     }
 
-    // @action
-    // private renderMarkerToMap = (marker: Doc) => {
-    //     const id = StrCast(marker.id);
-    //     const lat = NumCast(marker.lat);
-    //     const lng = NumCast(marker.lng);
-
-    //     return <Marker
-    //         key={id}
-    //         position={{ lat: lat, lng: lng }}
-    //         onClick={e => this.markerClickHandler(e, marker)}
-    //     />
-    // }
+    @action
+    private markerLoadHandler = (marker: google.maps.Marker, place: LocationData) => {
+        place.id ? this.markerMap[place.id] = marker : null;
+    }
 
     render() {
         const { Document, fieldKey, isContentActive: active } = this.props;
@@ -303,6 +222,7 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
                         zoom={this.zoom}
                         center={this.center}
                         onLoad={map => this.loadHandler(map)}
+                        options={mapOptions}
                     >
                         <Autocomplete
                             onLoad={this.setSearchBox}
@@ -310,49 +230,38 @@ export default class CollectionMapView extends CollectionSubView<MapSchema, Part
                             <input ref={this.inputRef} className="searchbox" type="text" placeholder="Search anywhere:" />
                         </Autocomplete>
 
-                        <div onLoad={this.setButton}>
-                            <div ref={this.buttonRef} className="add-button-UI" >
-                                <div className="add-button-Text">Add Marker</div>
-                            </div>
-                        </div>
-
-                        {this.myPlaces.map(place => (
+                        {this.myPlaces ? this.myPlaces.map(place =>
                             <Marker
-                                key={place.id}
                                 position={place.pos}
-                                // onLoad={marker => this.markerLoadHandler(marker, place)}
+                                onLoad={marker => this.markerLoadHandler(marker, place)}
                                 onClick={e => this.markerClickHandler(e, place)}
-                                draggable={true}
-                                onDragEnd={marker => this.handleDragMarker(marker, place)}
+                                draggable={false}
                             />
-                        ))}
+                        ) : null}
                         {this.infoWindowOpen && this.selectedPlace && (
-                            <InfoBox
-                                // anchor={this.markerMap[this.selectedPlace.id]}
-                                // onCloseClick={this.handleInfoWindowClose}
-                                position={this.selectedPlace.pos}
-                            // options={{ enableEventPropagation: true }}
+                            <InfoWindow
+                                anchor={this.markerMap[this.selectedPlace.id!]}
+                                onCloseClick={this.handleInfoWindowClose}
                             >
                                 <div style={{ backgroundColor: 'white', opacity: 0.75, padding: 12 }}>
                                     <div style={{ fontSize: 16 }}>
                                         <div>
-                                            <a>a link to another node</a>
-                                            <hr />
-                                        </div>
-                                        <div>
-                                            <a>a link to another node</a>
+                                            <img src="http://placekitten.com/200/300" />
                                             <hr />
-                                        </div>
-                                        <div>
-                                            <a>a link to another node</a>
+                                            <form>
+                                                <label>Title: </label><br />
+                                                <input type="text" id="fname" name="fname"></input><br />
+                                                <label>Desription: </label><br />
+                                                <textarea style={{ height: 150 }} id="lname" name="lname" placeholder="Notes, a short description of this location, a brief comment, etc."></textarea>
+                                            </form>
                                             <hr />
-                                        </div>
-                                        <div>
-                                            <button>New +</button>
+                                            <div>
+                                                <button>New link+</button>
+                                            </div>
                                         </div>
                                     </div>
                                 </div>
-                            </InfoBox>
+                            </InfoWindow>
                         )}
                     </GoogleMap>
                 </div>
-- 
cgit v1.2.3-70-g09d2

