import { GoogleApiWrapper, Map, MapProps, Marker } from "google-maps-react"; import { observer } from "mobx-react"; import { Doc, Opt, DocListCast } from "../../../new_fields/Doc"; import { documentSchema } from "../../../new_fields/documentSchemas"; import { Id } from "../../../new_fields/FieldSymbols"; import { makeInterface } from "../../../new_fields/Schema"; import { Cast, NumCast, ScriptCast, StrCast } from "../../../new_fields/Types"; import { TraceMobx } from "../../../new_fields/util"; import "./CollectionMapView.scss"; import { CollectionSubView } from "./CollectionSubView"; import React = require("react"); import { DocumentManager } from "../../util/DocumentManager"; import { UndoManager } from "../../util/UndoManager"; type MapSchema = makeInterface<[typeof documentSchema]>; const MapSchema = makeInterface(documentSchema); export type LocationData = google.maps.LatLngLiteral & { address?: string }; @observer class CollectionMapView extends CollectionSubView & { google: any }>(MapSchema) { getLocation = (doc: Opt, fieldKey: string) => { if (doc) { let lat: Opt = Cast(doc[fieldKey + "-lat"], "number", null); let lng: Opt = Cast(doc[fieldKey + "-lng"], "number", null); const zoom: Opt = Cast(doc[fieldKey + "-zoom"], "number", null); const address = Cast(doc[fieldKey + "-address"], "string", null); if (address) { // use geo service to convert to lat/lng lat = lat; lng = lng; } return lat !== undefined && lng !== undefined ? ({ lat, lng, zoom }) : undefined; } return undefined; } renderMarker(layout: Doc, icon: Opt) { const location = this.getLocation(layout, "mapLocation"); return !location ? (null) : { this.layoutDoc[this.props.fieldKey + "-mapCenter-lat"] = 0; this.layoutDoc[this.props.fieldKey + "-mapCenter-lat"] = location.lat; this.layoutDoc[this.props.fieldKey + "-mapCenter-lng"] = location.lng; location.zoom && (this.layoutDoc[this.props.fieldKey + "-mapCenter-zoom"] = location.zoom); if (layout.isLinkButton && DocListCast(layout.links).length) { const batch = UndoManager.StartBatch("follow link click"); await DocumentManager.Instance.FollowLink(undefined, layout, (doc: Doc, where: string, finished?: () => void) => { this.props.addDocTab(doc, where); finished?.(); }, false, this.props.ContainingCollectionDoc, batch.end, undefined); } else { ScriptCast(layout.onClick)?.script.run({ this: layout, self: Cast(layout.rootDocument, Doc, null) || layout }); } }} icon={icon} />; } render() { const { childLayoutPairs } = this; const { Document } = this.props; let center = this.getLocation(Document, this.props.fieldKey + "-mapCenter"); if (center === undefined) { center = childLayoutPairs.map(pair => this.getLocation(pair.layout, "mapLocation")).find(layout => layout); if (center === undefined) { center = { lat: 35.1592238, lng: -98.444512, zoom: 15 }; // nowhere, OK } } TraceMobx(); return
e.stopPropagation()} onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()} > console.log("ON_BOUNDS_CHANGED", props, map, e)} onRecenter={(props, map, e) => console.log("ON_RECENTER", props, map, e)} onDragend={(centerMoved, center) => console.log("ON_DRAGEND", centerMoved, center)} onProjectionChanged={(props, map, e) => console.log("ON_PROJ_CHANGED", props, map, e)} onCenterChanged={((props, map, e) => { console.log("ON_CENTER_CHANGED", props, map, e); Document[this.props.fieldKey + "-mapCenter-lat"] = typeof e?.center?.lat === "number" ? e.center.lat : center!.lat; Document[this.props.fieldKey + "-mapCenter-lng"] = typeof e?.center?.lng === "number" ? e.center.lng : center!.lng; })} > {childLayoutPairs.map(({ layout }) => { let icon: Opt, iconUrl: Opt; if ((iconUrl = StrCast(Document.mapIconUrl, null))) { const iconWidth = NumCast(layout["mapLocation-iconWidth"], 45); const iconHeight = NumCast(layout["mapLocation-iconHeight"], 45); const iconSize = new google.maps.Size(iconWidth, iconHeight); icon = { size: iconSize, scaledSize: iconSize, url: iconUrl }; } return this.renderMarker(layout, icon); })}
; } } const LoadingContainer = () => { return
; }; export default GoogleApiWrapper({ apiKey: process.env.GOOGLE_MAPS!, LoadingContainer })(CollectionMapView) as any;