From 348e794e7ff341a4358be6ed9515fc6ae723092e Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Sun, 12 Apr 2020 21:36:26 -0700 Subject: rough pass at collection map view --- src/client/views/collections/CollectionMapView.scss | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/client/views/collections/CollectionMapView.scss (limited to 'src/client/views/collections/CollectionMapView.scss') diff --git a/src/client/views/collections/CollectionMapView.scss b/src/client/views/collections/CollectionMapView.scss new file mode 100644 index 000000000..c74433902 --- /dev/null +++ b/src/client/views/collections/CollectionMapView.scss @@ -0,0 +1,4 @@ +.collectionMapView-contents { + width: 100%; + height: 100%; +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 87268612b9b765d74f1a5317b0894be0ceb1dfd1 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 13 Apr 2020 16:43:50 -0400 Subject: fixed map view pointer events. --- src/client/views/collections/CollectionMapView.scss | 3 +++ src/client/views/collections/CollectionMapView.tsx | 8 ++++---- src/client/views/collections/CollectionView.tsx | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src/client/views/collections/CollectionMapView.scss') diff --git a/src/client/views/collections/CollectionMapView.scss b/src/client/views/collections/CollectionMapView.scss index c74433902..df7853da6 100644 --- a/src/client/views/collections/CollectionMapView.scss +++ b/src/client/views/collections/CollectionMapView.scss @@ -1,4 +1,7 @@ .collectionMapView-contents { width: 100%; height: 100%; +} +.collectionMapView-contents-none { + pointer-events: none; } \ No newline at end of file diff --git a/src/client/views/collections/CollectionMapView.tsx b/src/client/views/collections/CollectionMapView.tsx index b67daeb53..5075bbf7a 100644 --- a/src/client/views/collections/CollectionMapView.tsx +++ b/src/client/views/collections/CollectionMapView.tsx @@ -7,6 +7,7 @@ import { NumCast, StrCast } from "../../../new_fields/Types"; import { CollectionSubView } from "./CollectionSubView"; import { Utils } from "../../../Utils"; import { Opt } from "../../../new_fields/Doc"; +import "./CollectionMapView.scss"; type MapDocument = makeInterface<[typeof documentSchema]>; const MapDocument = makeInterface(documentSchema); @@ -25,11 +26,10 @@ class CollectionMapView extends CollectionSubView center.lng = childLayoutPairs.length ? NumCast(childLayoutPairs[0].layout.locationLng, 0) : 0; } return ( -
+
(this.props.active() && e.button === 0 && !e.ctrlKey) && e.stopPropagation()} > { return viewField as any as CollectionViewType; } - active = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || this.props.rootSelected(outsideReaction) || this.props.Document.forceActive || this._isChildActive || this.props.renderDepth === 0; + active = (outsideReaction?: boolean) => (this.props.isSelected(outsideReaction) || this.props.rootSelected(outsideReaction) || this.props.Document.forceActive || this._isChildActive || this.props.renderDepth === 0) ? true : false; whenActiveChanged = (isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive); -- cgit v1.2.3-70-g09d2 From 78986ae808dc9bbb5763e3f74097b7a1bc61f49a Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 13 Apr 2020 18:45:52 -0400 Subject: more mapview adjustments --- src/client/documents/Documents.ts | 4 - src/client/views/PreviewCursor.tsx | 2 +- .../views/collections/CollectionMapView.scss | 3 - src/client/views/collections/CollectionMapView.tsx | 104 ++++++++++++++------- 4 files changed, 69 insertions(+), 44 deletions(-) (limited to 'src/client/views/collections/CollectionMapView.scss') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 3f46c4013..e6f3b21ca 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -49,10 +49,6 @@ import { ContextMenuProps } from "../views/ContextMenuItem"; import { ContextMenu } from "../views/ContextMenu"; import { LinkBox } from "../views/nodes/LinkBox"; import { ScreenshotBox } from "../views/nodes/ScreenshotBox"; -import CollectionMapView from "../views/collections/CollectionMapView"; -import LocationField, { LocationData } from "../../new_fields/LocationField"; -import { action } from "mobx"; -const requestImageSize = require('../util/request-image-size'); const path = require('path'); export interface DocumentOptions { diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 92ba13d2f..df30c1215 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -113,7 +113,7 @@ export class PreviewCursor extends React.Component<{}> { addLiveText: (doc: Doc) => void, getTransform: () => Transform, addDocument: (doc: Doc) => boolean, - nudge: (nudgeX: number, nudgeY: number) => void) { + nudge: (nudgeX: number, nudgeY: number) => boolean) { this._clickPoint = [x, y]; this._onKeyPress = onKeyPress; this._addLiveTextDoc = addLiveText; diff --git a/src/client/views/collections/CollectionMapView.scss b/src/client/views/collections/CollectionMapView.scss index df7853da6..c74433902 100644 --- a/src/client/views/collections/CollectionMapView.scss +++ b/src/client/views/collections/CollectionMapView.scss @@ -1,7 +1,4 @@ .collectionMapView-contents { width: 100%; height: 100%; -} -.collectionMapView-contents-none { - pointer-events: none; } \ No newline at end of file diff --git a/src/client/views/collections/CollectionMapView.tsx b/src/client/views/collections/CollectionMapView.tsx index 5075bbf7a..569f8ba7a 100644 --- a/src/client/views/collections/CollectionMapView.tsx +++ b/src/client/views/collections/CollectionMapView.tsx @@ -1,13 +1,20 @@ +import { GoogleApiWrapper, Map, MapProps, Marker } from "google-maps-react"; import { observer } from "mobx-react"; -import { makeInterface } from "../../../new_fields/Schema"; +import { Doc, Opt, DocListCast } from "../../../new_fields/Doc"; import { documentSchema } from "../../../new_fields/documentSchemas"; -import React = require("react"); -import { Map, Marker, MapProps, GoogleApiWrapper } from "google-maps-react"; -import { NumCast, StrCast } from "../../../new_fields/Types"; -import { CollectionSubView } from "./CollectionSubView"; -import { Utils } from "../../../Utils"; -import { Opt } from "../../../new_fields/Doc"; +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"; +import { returnTrue } from "../../../Utils"; +import { CancellationError } from "bluebird"; +import { ln } from "shelljs"; +import { dfareporting } from "googleapis/build/src/apis/dfareporting"; type MapDocument = makeInterface<[typeof documentSchema]>; const MapDocument = makeInterface(documentSchema); @@ -17,28 +24,65 @@ export type LocationData = google.maps.LatLngLiteral & { address?: string }; @observer class CollectionMapView extends CollectionSubView & { google: any }>(MapDocument) { + getLocation = (doc: Opt, fieldKey: string, defaultLocation?: LocationData) => { + if (doc) { + let lat: Opt = Cast(doc[fieldKey + "-lat"], "number", null); + let lng: Opt = Cast(doc[fieldKey + "-lng"], "number", null); + const address = Cast(doc[fieldKey + "-address"], "string", null); + if (address) { + // use geo service to convert to lat/lng + lat = lat; + lng = lng; + } + if (lat === undefined) lat = defaultLocation?.lat; + if (lng === undefined) lng = defaultLocation?.lng; + return ({ lat, lng }); + } + return ({ lat: 35.1592238, lng: -98.4466577 }); + } + renderMarker(layout: Doc, icon: Opt) { + const location = this.getLocation(layout, "location"); + return location.lat === undefined || location.lng === undefined ? (null) : + { + this.props.Document.mapCenterLat = location.lat; + this.props.Document.mapCenterLng = location.lng; + 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, props } = this; - const { Document } = props; - const center: LocationData = { lat: NumCast(Document.mapCenterLat), lng: NumCast(Document.mapCenterLng) }; - if (!center.lat) { - center.lat = childLayoutPairs.length ? NumCast(childLayoutPairs[0].layout.locationLat, 0) : 0; - center.lng = childLayoutPairs.length ? NumCast(childLayoutPairs[0].layout.locationLng, 0) : 0; + const { childLayoutPairs } = this; + const { Document } = this.props; + let center = this.getLocation(Document, this.props.fieldKey + "-mapCenter"); + if (center.lat === undefined) { + center = this.getLocation(childLayoutPairs.map(pair => pair.layout).find(returnTrue), "location", { lat: 35.1592238, lng: -98.4466577 }); } - return ( -
(this.props.active() && e.button === 0 && !e.ctrlKey) && e.stopPropagation()} > + TraceMobx(); + return center.lat === undefined || center.lng === undefined ? (null) : +
e.stopPropagation()} + onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()} > {childLayoutPairs.map(({ layout }) => { - const location: LocationData = { - lat: NumCast(childLayoutPairs[0].layout.locationLat, 0), - lng: NumCast(childLayoutPairs[0].layout.locationLng, 0) - }; let icon: Opt, iconUrl: Opt; if ((iconUrl = StrCast(Document.mapIconUrl, null))) { const iconSize = new google.maps.Size(NumCast(layout.mapIconWidth, 45), NumCast(layout.mapIconHeight, 45)); @@ -48,22 +92,10 @@ class CollectionMapView extends CollectionSubView url: iconUrl }; } - return ( - { - Document.mapCenterLat = location.lat; - Document.mapCenterLng = location.lng; - }} - icon={icon} - /> - ); + return this.renderMarker(layout, icon); })} -
- ); +
; } } -- cgit v1.2.3-70-g09d2 From a888dacc8e6a6400d52cdded0015e05ac5581d3d Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Tue, 14 Apr 2020 00:31:20 -0700 Subject: chrome dropdown changes and custom loading container for mapview --- .../views/collections/CollectionMapView.scss | 18 +++++++++++++ src/client/views/collections/CollectionMapView.tsx | 31 +++++++++++++--------- .../views/collections/CollectionViewChromes.tsx | 18 ++++++------- 3 files changed, 46 insertions(+), 21 deletions(-) (limited to 'src/client/views/collections/CollectionMapView.scss') diff --git a/src/client/views/collections/CollectionMapView.scss b/src/client/views/collections/CollectionMapView.scss index c74433902..4956ad946 100644 --- a/src/client/views/collections/CollectionMapView.scss +++ b/src/client/views/collections/CollectionMapView.scss @@ -1,4 +1,22 @@ .collectionMapView-contents { width: 100%; height: 100%; +} + +.loadingWrapper { + width: 100%; + height: 100%; + background-color: yellow; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + text-align: center; + + .loadingGif { + align-self: center; + justify-self: center; + width: 20%; + height: 20% + } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionMapView.tsx b/src/client/views/collections/CollectionMapView.tsx index 44bb22827..6d5dcdf1d 100644 --- a/src/client/views/collections/CollectionMapView.tsx +++ b/src/client/views/collections/CollectionMapView.tsx @@ -11,20 +11,21 @@ import { CollectionSubView } from "./CollectionSubView"; import React = require("react"); import { DocumentManager } from "../../util/DocumentManager"; import { UndoManager } from "../../util/UndoManager"; +import * as ReactDOM from 'react-dom'; -type MapDocument = makeInterface<[typeof documentSchema]>; -const MapDocument = makeInterface(documentSchema); +type MapSchema = makeInterface<[typeof documentSchema]>; +const MapSchema = makeInterface(documentSchema); export type LocationData = google.maps.LatLngLiteral & { address?: string }; @observer -class CollectionMapView extends CollectionSubView & { google: any }>(MapDocument) { +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); - let zoom: Opt = Cast(doc[fieldKey + "-zoom"], "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 @@ -79,12 +80,12 @@ class CollectionMapView extends CollectionSubView google={this.props.google} zoom={center.zoom || 10} initialCenter={center} - center={center} - onBoundsChanged={e => console.log(e)} - onRecenter={e => console.log(e)} - onDragend={(centerMoved, center) => console.log(centerMoved, center)} - onProjectionChanged={e => console.log(e)} - onCenterChanged={(e => { + onBoundsChanged={(props, map, e) => 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; })} @@ -92,7 +93,9 @@ class CollectionMapView extends CollectionSubView {childLayoutPairs.map(({ layout }) => { let icon: Opt, iconUrl: Opt; if ((iconUrl = StrCast(Document.mapIconUrl, null))) { - const iconSize = new google.maps.Size(NumCast(layout["mapLocation-iconWidth"], 45), NumCast(layout["mapLocation-iconHeight"], 45)); + 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, @@ -107,4 +110,8 @@ class CollectionMapView extends CollectionSubView } -export default GoogleApiWrapper({ apiKey: process.env.GOOGLE_MAPS! })(CollectionMapView) as any; \ No newline at end of file +const LoadingContainer = () => { + return
; +}; + +export default GoogleApiWrapper({ apiKey: process.env.GOOGLE_MAPS!, LoadingContainer })(CollectionMapView) as any; \ No newline at end of file diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index ba95dce00..0940e9186 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -402,15 +402,15 @@ export class CollectionViewBaseChrome extends React.Component - - - - - - - - - + {Object.values(CollectionViewType).map(type => ["invalid", "docking"].includes(type) ? (null) : ( + + ))}
-- cgit v1.2.3-70-g09d2 From 3494d987b72b1e60bf1ded41443391952578e323 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Apr 2020 13:32:33 -0400 Subject: fixed maps to support drag/drop, and fixed to work with docs that just have an address. --- .../views/collections/CollectionMapView.scss | 6 ++- src/client/views/collections/CollectionMapView.tsx | 59 ++++++++++++++-------- .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- 3 files changed, 44 insertions(+), 23 deletions(-) (limited to 'src/client/views/collections/CollectionMapView.scss') diff --git a/src/client/views/collections/CollectionMapView.scss b/src/client/views/collections/CollectionMapView.scss index 4956ad946..cb58b1750 100644 --- a/src/client/views/collections/CollectionMapView.scss +++ b/src/client/views/collections/CollectionMapView.scss @@ -1,6 +1,10 @@ -.collectionMapView-contents { +.collectionMapView { width: 100%; height: 100%; + .collectionMapView-contents { + width: 100%; + height: 100%; + } } .loadingWrapper { diff --git a/src/client/views/collections/CollectionMapView.tsx b/src/client/views/collections/CollectionMapView.tsx index fced52275..a80f0557f 100644 --- a/src/client/views/collections/CollectionMapView.tsx +++ b/src/client/views/collections/CollectionMapView.tsx @@ -40,10 +40,25 @@ class CollectionMapView extends CollectionSubView & getLocation = (doc: Opt, fieldKey: string): Opt => { if (doc) { - const lat: Opt = Cast(doc[fieldKey + "-lat"], "number", null); - const lng: Opt = Cast(doc[fieldKey + "-lng"], "number", null); - const zoom: Opt = Cast(doc[fieldKey + "-zoom"], "number", null); - return lat !== undefined && lng !== undefined ? ({ lat, lng, zoom }) : undefined; + const lat: Opt = Cast(doc[fieldKey + "-lat"], "number", null) || (Cast(doc[fieldKey + "-lat"], "string", null) && Number(Cast(doc[fieldKey + "-lat"], "string", null))) || undefined; + const lng: Opt = Cast(doc[fieldKey + "-lng"], "number", null) || (Cast(doc[fieldKey + "-lng"], "string", null) && Number(Cast(doc[fieldKey + "-lng"], "string", null))) || undefined; + const zoom: Opt = Cast(doc[fieldKey + "-zoom"], "number", null) || (Cast(doc[fieldKey + "-zoom"], "string", null) && Number(Cast(doc[fieldKey + "-zoom"], "string", null))) || undefined; + const address: Opt = Cast(doc[fieldKey + "-address"], "string", null); + if (lat !== undefined && lng !== undefined) { + return ({ lat, lng, zoom }); + } else if (address) { + setTimeout(() => { + const target = `${base}address=${address.replace(/\s+/g, "+")}&key=${process.env.GOOGLE_MAPS_GEO!}`; + requestPromise.get(target).then(action((res: any) => { + const { lat, lng } = JSON.parse(res).results[0].geometry.location; + if (doc[fieldKey + "-lat"] !== lat || doc[fieldKey + "-lng"] !== lng) { + Doc.SetInPlace(doc, fieldKey + "-lat", lat, true); + Doc.SetInPlace(doc, fieldKey + "-lng", lng, true); + } + })); + }); + return ({ lat: 35.1592238, lng: -98.444512, zoom: 15 }); + } } return undefined; } @@ -152,23 +167,25 @@ class CollectionMapView extends CollectionSubView & } } TraceMobx(); - return
e.stopPropagation()} - onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()} > - { - Document[this.props.fieldKey + "-mapCenter-lat"] = map.center.lat(); - Document[this.props.fieldKey + "-mapCenter-lng"] = map.center.lng(); - }))} - > - {this.contents} - + return
+
e.stopPropagation()} + onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()} > + { + Document[this.props.fieldKey + "-mapCenter-lat"] = map.center.lat(); + Document[this.props.fieldKey + "-mapCenter-lng"] = map.center.lng(); + }))} + > + {this.contents} + +
; } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 9dd3d640b..454c3a5f2 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -309,7 +309,7 @@ export class MarqueeView extends React.Component { + getCollection = (selected: Doc[], asTemplate: boolean, isBackground?: boolean) => { const bounds = this.Bounds; // const inkData = this.ink ? this.ink.inkData : undefined; const creator = asTemplate ? Docs.Create.StackingDocument : Docs.Create.FreeformDocument; -- cgit v1.2.3-70-g09d2 From 3d4a7582dcd0df151f9571fdeb24507acefe49e1 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Tue, 14 Apr 2020 13:48:25 -0700 Subject: map view cleanup --- .../views/collections/CollectionMapView.scss | 7 +- src/client/views/collections/CollectionMapView.tsx | 142 ++++++++++++--------- 2 files changed, 87 insertions(+), 62 deletions(-) (limited to 'src/client/views/collections/CollectionMapView.scss') diff --git a/src/client/views/collections/CollectionMapView.scss b/src/client/views/collections/CollectionMapView.scss index cb58b1750..2e642be6b 100644 --- a/src/client/views/collections/CollectionMapView.scss +++ b/src/client/views/collections/CollectionMapView.scss @@ -1,6 +1,7 @@ .collectionMapView { width: 100%; height: 100%; + .collectionMapView-contents { width: 100%; height: 100%; @@ -10,7 +11,7 @@ .loadingWrapper { width: 100%; height: 100%; - background-color: yellow; + background-color: pink; display: flex; flex-direction: column; justify-content: center; @@ -20,7 +21,7 @@ .loadingGif { align-self: center; justify-self: center; - width: 20%; - height: 20% + width: 50px; + height: 50px; } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionMapView.tsx b/src/client/views/collections/CollectionMapView.tsx index a80f0557f..b6772c5a2 100644 --- a/src/client/views/collections/CollectionMapView.tsx +++ b/src/client/views/collections/CollectionMapView.tsx @@ -4,14 +4,13 @@ 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, BoolCast } from "../../../new_fields/Types"; -import { TraceMobx } from "../../../new_fields/util"; +import { Cast, NumCast, ScriptCast, StrCast } from "../../../new_fields/Types"; import "./CollectionMapView.scss"; import { CollectionSubView } from "./CollectionSubView"; import React = require("react"); import { DocumentManager } from "../../util/DocumentManager"; import { UndoManager, undoBatch } from "../../util/UndoManager"; -import { IReactionDisposer, reaction, action, computed } from "mobx"; +import { IReactionDisposer, reaction, computed, runInAction } from "mobx"; import requestPromise = require("request-promise"); type MapSchema = makeInterface<[typeof documentSchema]>; @@ -23,21 +22,31 @@ export type LocationData = google.maps.LatLngLiteral & { zoom?: number; }; -const base = "https://maps.googleapis.com/maps/api/geocode/json?"; +// Nowhere, Oklahoma +const defaultLocation = { lat: 35.1592238, lng: -98.444512, zoom: 15 }; + +const query = async (data: string | google.maps.LatLngLiteral) => { + const contents = typeof data === "string" ? `address=${data.replace(/\s+/g, "+")}` : `latlng=${data.lat},${data.lng}`; + const target = `https://maps.googleapis.com/maps/api/geocode/json?${contents}&key=${process.env.GOOGLE_MAPS_GEO}`; + return JSON.parse(await requestPromise.get(target)); +}; @observer class CollectionMapView extends CollectionSubView & { google: any }>(MapSchema) { - // private mapRef = React.createRef(); - // private get map() { - // return (this.mapRef.current as any).map; - // } - private _cancelAddrReq = new Map(); private _cancelLocReq = new Map(); private addressUpdaters: IReactionDisposer[] = []; private latlngUpdaters: IReactionDisposer[] = []; + /** + * Note that all the uses of runInAction below are not included + * as a way to update observables (documents handle this already + * in their property setters), but rather to create a single bulk + * update and thus prevent uneeded invocations of the location- + * and address–updating reactions. + */ + getLocation = (doc: Opt, fieldKey: string): Opt => { if (doc) { const lat: Opt = Cast(doc[fieldKey + "-lat"], "number", null) || (Cast(doc[fieldKey + "-lat"], "string", null) && Number(Cast(doc[fieldKey + "-lat"], "string", null))) || undefined; @@ -48,27 +57,31 @@ class CollectionMapView extends CollectionSubView & return ({ lat, lng, zoom }); } else if (address) { setTimeout(() => { - const target = `${base}address=${address.replace(/\s+/g, "+")}&key=${process.env.GOOGLE_MAPS_GEO!}`; - requestPromise.get(target).then(action((res: any) => { - const { lat, lng } = JSON.parse(res).results[0].geometry.location; - if (doc[fieldKey + "-lat"] !== lat || doc[fieldKey + "-lng"] !== lng) { - Doc.SetInPlace(doc, fieldKey + "-lat", lat, true); - Doc.SetInPlace(doc, fieldKey + "-lng", lng, true); + query(address).then(({ results }) => { + if (results?.length) { + const { lat, lng } = results[0].geometry.location; + if (doc[fieldKey + "-lat"] !== lat || doc[fieldKey + "-lng"] !== lng) { + runInAction(() => { + Doc.SetInPlace(doc, fieldKey + "-lat", lat, true); + Doc.SetInPlace(doc, fieldKey + "-lng", lng, true); + }); + } } - })); + }); }); - return ({ lat: 35.1592238, lng: -98.444512, zoom: 15 }); + return defaultLocation; } } return undefined; } - markerClick = action(async (layout: Doc, location: LocationData) => { - //this.map.panTo(location); + private markerClick = async (layout: Doc, { lat, lng, zoom }: LocationData) => { const batch = UndoManager.StartBatch("marker click"); - 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); + runInAction(() => { + this.layoutDoc[this.props.fieldKey + "-mapCenter-lat"] = lat; + this.layoutDoc[this.props.fieldKey + "-mapCenter-lng"] = lng; + zoom && (this.layoutDoc[this.props.fieldKey + "-mapCenter-zoom"] = zoom); + }); if (layout.isLinkButton && DocListCast(layout.links).length) { await DocumentManager.Instance.FollowLink(undefined, layout, (doc: Doc, where: string, finished?: () => void) => { this.props.addDocTab(doc, where); @@ -78,7 +91,7 @@ class CollectionMapView extends CollectionSubView & ScriptCast(layout.onClick)?.script.run({ this: layout, self: Cast(layout.rootDocument, Doc, null) || layout }); batch.end(); } - }); + } renderMarkerIcon(layout: Doc) { const iconUrl = StrCast(this.props.Document.mapIconUrl, null); @@ -93,6 +106,7 @@ class CollectionMapView extends CollectionSubView & }; } } + renderMarker(layout: Doc) { const location = this.getLocation(layout, "mapLocation"); return !location ? (null) : @@ -116,14 +130,14 @@ class CollectionMapView extends CollectionSubView & ({ lat, lng }) => { if (this._cancelLocReq.get(layout[Id])) { this._cancelLocReq.set(layout[Id], false); - } - else if (lat !== undefined && lng !== undefined) { - const target = `${base}latlng=${NumCast(lat)},${NumCast(lng)}&key=${process.env.GOOGLE_MAPS_GEO!}`; - requestPromise.get(target).then(res => { - const formatted_address = JSON.parse(res).results[0].formatted_address || ""; - if (formatted_address !== layout["mapLocation-address"]) { - this._cancelAddrReq.set(layout[Id], true); - Doc.SetInPlace(layout, "mapLocation-address", formatted_address, true); + } else if (lat !== undefined && lng !== undefined) { + query({ lat: NumCast(lat), lng: NumCast(lng) }).then(({ results }) => { + if (results?.length) { + const { formatted_address } = results[0]; + if (formatted_address !== layout["mapLocation-address"]) { + this._cancelAddrReq.set(layout[Id], true); + Doc.SetInPlace(layout, "mapLocation-address", formatted_address, true); + } } }); } @@ -134,54 +148,58 @@ class CollectionMapView extends CollectionSubView & ({ address }) => { if (this._cancelAddrReq.get(layout[Id])) { this._cancelAddrReq.set(layout[Id], false); - } - else if (address?.length) { - const target = `${base}address=${address.replace(/\s+/g, "+")}&key=${process.env.GOOGLE_MAPS_GEO!}`; - requestPromise.get(target).then(action((res: any) => { - const { geometry, formatted_address } = JSON.parse(res).results[0]; - const { lat, lng } = geometry.location; - if (layout["mapLocation-lat"] !== lat || layout["mapLocation-lng"] !== lng) { - this._cancelLocReq.set(layout[Id], true); - Doc.SetInPlace(layout, "mapLocation-lat", lat, true); - Doc.SetInPlace(layout, "mapLocation-lng", lng, true); - } - if (formatted_address !== address) { - this._cancelAddrReq.set(layout[Id], true); - Doc.SetInPlace(layout, "mapLocation-address", formatted_address, true); + } else if (address?.length) { + query(address).then(({ results }) => { + if (results?.length) { + const { geometry, formatted_address } = results[0]; + const { lat, lng } = geometry.location; + runInAction(() => { + if (layout["mapLocation-lat"] !== lat || layout["mapLocation-lng"] !== lng) { + this._cancelLocReq.set(layout[Id], true); + Doc.SetInPlace(layout, "mapLocation-lat", lat, true); + Doc.SetInPlace(layout, "mapLocation-lng", lng, true); + } + if (formatted_address !== address) { + this._cancelAddrReq.set(layout[Id], true); + Doc.SetInPlace(layout, "mapLocation-address", formatted_address, true); + } + }); } - })); + }); } } )); return this.renderMarker(layout); }); } + render() { const { childLayoutPairs } = this; - const { Document } = this.props; - let center = this.getLocation(Document, this.props.fieldKey + "-mapCenter"); + const { Document, fieldKey, active, google } = this.props; + let center = this.getLocation(Document, 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 + center = defaultLocation; } } - TraceMobx(); return
e.stopPropagation()} onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()} > { - Document[this.props.fieldKey + "-mapCenter-lat"] = map.center.lat(); - Document[this.props.fieldKey + "-mapCenter-lng"] = map.center.lng(); - }))} + onDragend={undoBatch((_props: MapProps, map: google.maps.Map) => { + const { lat, lng } = map.getCenter(); + runInAction(() => { + Document[fieldKey + "-mapCenter-lat"] = lat(); + Document[fieldKey + "-mapCenter-lng"] = lng(); + }); + })} > {this.contents} @@ -191,5 +209,11 @@ class CollectionMapView extends CollectionSubView & } -const LoadingContainer = () =>
; -export default GoogleApiWrapper({ apiKey: process.env.GOOGLE_MAPS!, LoadingContainer })(CollectionMapView) as any; \ No newline at end of file +export default GoogleApiWrapper({ + apiKey: process.env.GOOGLE_MAPS!, + LoadingContainer: () => ( +
+ +
+ ) +})(CollectionMapView) as any; \ No newline at end of file -- cgit v1.2.3-70-g09d2 From a9613d73947ee9b000c695b8f3d7685feed96a27 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Apr 2020 17:37:20 -0400 Subject: fixed goldenlayout borders. made filter flyout semistransparent. fixed map to stay inbounds when filter is expanded. --- src/client/goldenLayout.js | 4 +++- src/client/views/collections/CollectionMapView.scss | 3 +++ src/client/views/collections/CollectionView.scss | 1 - src/client/views/collections/CollectionView.tsx | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections/CollectionMapView.scss') diff --git a/src/client/goldenLayout.js b/src/client/goldenLayout.js index b510385ff..2d4283b02 100644 --- a/src/client/goldenLayout.js +++ b/src/client/goldenLayout.js @@ -1551,7 +1551,7 @@ }, dimensions: { borderWidth: 5, - borderGrabWidth: 15, + borderGrabWidth: 5, minItemHeight: 10, minItemWidth: 10, headerHeight: 20, @@ -2796,11 +2796,13 @@ if (this._isVertical) { dragHandle.css('top', -handleExcessPos); dragHandle.css('height', this._size + handleExcessSize); + element.css('cursor', 'row-resize'); element.addClass('lm_vertical'); element['height'](this._size); } else { dragHandle.css('left', -handleExcessPos); dragHandle.css('width', this._size + handleExcessSize); + element.css('cursor', 'col-resize'); element.addClass('lm_horizontal'); element['width'](this._size); } diff --git a/src/client/views/collections/CollectionMapView.scss b/src/client/views/collections/CollectionMapView.scss index cb58b1750..7e4f9a0f4 100644 --- a/src/client/views/collections/CollectionMapView.scss +++ b/src/client/views/collections/CollectionMapView.scss @@ -4,6 +4,9 @@ .collectionMapView-contents { width: 100%; height: 100%; + > div { + position: unset !important; // when the sidebar filter flys out, this prevents the map from extending outside the document box + } } } diff --git a/src/client/views/collections/CollectionView.scss b/src/client/views/collections/CollectionView.scss index b92c5fdd1..a0b73b90f 100644 --- a/src/client/views/collections/CollectionView.scss +++ b/src/client/views/collections/CollectionView.scss @@ -11,7 +11,6 @@ height: 100%; overflow: hidden; // bcz: used to be 'auto' which would create scrollbars when there's a floating doc that's not visible. not sure if that's better, but the scrollbars are annoying... - .collectionTimeView-dragger { background-color: lightgray; height: 40px; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index f94277862..13a657800 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -389,7 +389,7 @@ export class CollectionView extends Touchable { return false; }), returnFalse, action(() => this._facetWidth = this.facetWidth() < 15 ? Math.min(this.props.PanelWidth() - 25, 200) : 0)); } - filterBackground = () => "dimGray"; + filterBackground = () => "rgba(105, 105, 105, 0.432)"; get ignoreFields() { return ["_docFilters", "_docRangeFilters"]; } // this makes the tree view collection ignore these filters (otherwise, the filters would filter themselves) @computed get scriptField() { const scriptText = "setDocFilter(containingTreeView, heading, this.title, checked)"; -- cgit v1.2.3-70-g09d2