aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/MapBox/MapBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/MapBox/MapBox.tsx')
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx264
1 files changed, 148 insertions, 116 deletions
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 7d3dcb811..f1f6b0756 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -4,17 +4,19 @@ import BingMapsReact from 'bingmaps-react';
import { EditableText } from 'browndash-components';
import e from 'connect-flash';
import { truncateSync } from 'fs';
-import { action, computed, IReactionDisposer, observable, ObservableMap, runInAction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, DocListCast, Opt, WidthSym } from '../../../../fields/Doc';
import { Id } from '../../../../fields/FieldSymbols';
import { InkTool } from '../../../../fields/InkField';
+import { ScriptField } from '../../../../fields/ScriptField';
import { NumCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils';
+import { emptyFunction, returnAll, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils';
import { Docs } from '../../../documents/Documents';
import { DragManager } from '../../../util/DragManager';
import { SnappingManager } from '../../../util/SnappingManager';
+import { Transform } from '../../../util/Transform';
import { UndoManager } from '../../../util/UndoManager';
import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm';
import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent';
@@ -23,8 +25,9 @@ import { MarqueeAnnotator } from '../../MarqueeAnnotator';
import { AnchorMenu } from '../../pdf/AnchorMenu';
import { Annotation } from '../../pdf/Annotation';
import { SidebarAnnos } from '../../SidebarAnnos';
+import { DocumentView } from '../DocumentView';
import { FieldView, FieldViewProps } from '../FieldView';
-import { PinProps } from '../trails';
+import { PinProps, PresBox } from '../trails';
import './MapBox.scss';
import { MapBoxInfoWindow } from './MapBoxInfoWindow';
// amongus
@@ -126,11 +129,23 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
static _hadSelection: boolean = false;
private _sidebarRef = React.createRef<SidebarAnnos>();
private _ref: React.RefObject<HTMLDivElement> = React.createRef();
-
+ private _disposer: {[key:string]:IReactionDisposer} = {}
componentDidMount() {
this.props.setContentView?.(this);
+ this._disposer.location = reaction(() => ({lat:this.rootDoc.latitude, lng:this.rootDoc.longitude}),
+ (locationObject) => {
+
+ //TODO: SAVE ZOOM? VIEW STYLE?
+ this._bingMap.current.setView({
+ center: new this.MicrosoftMaps.Location(locationObject.lat, locationObject.lng),
+ });
+
+ }, {fireImmediately: true});
}
+ componentWillUnmount(): void {
+ Object.keys(this._disposer).forEach(key => this._disposer[key]?.())
+ }
// iterate allMarkers to size, center, and zoom map to contain all markers
private fitBounds = (map: google.maps.Map) => {
const curBounds = map.getBounds() ?? new window.google.maps.LatLngBounds();
@@ -240,7 +255,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
map: map,
});
map.panTo(position);
- const mapMarker = Docs.Create.MapMarkerDocument(NumCast(position.lat()), NumCast(position.lng()), false, [], {});
+ const mapMarker = Docs.Create.PushpinDocument(NumCast(position.lat()), NumCast(position.lng()), false, [], {});
this.addDocument(mapMarker, this.annotationKey);
};
@@ -368,7 +383,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
if (existingMarker) {
Doc.AddDocToList(existingMarker, 'data', doc);
} else {
- const marker = Docs.Create.MapMarkerDocument(NumCast(doc.lat), NumCast(doc.lng), false, [doc], {});
+ const marker = Docs.Create.PushpinDocument(NumCast(doc.lat), NumCast(doc.lng), false, [doc], {});
this.addDocument(marker, this.annotationKey);
}
}
@@ -512,7 +527,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
);
}
- getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => AnchorMenu.Instance?.GetAnchor(this._savedAnnotations, addAsAnnotation) ?? this.rootDoc;
+ // Old get anchor function
+ // getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => AnchorMenu.Instance?.GetAnchor(this._savedAnnotations, addAsAnnotation) ?? this.rootDoc;
/**
* render contents in allMapMarkers (e.g. images with exifData) into google maps as map marker
@@ -592,57 +608,78 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
entityType: 'PopulatedPlace',
};
- @action
- updateView = () => {
- this._bingMap.current.setView({
- center: new this.MicrosoftMaps.Location(this.dataDoc.latitude, this.dataDoc.longitude),
- // zoom: location
- });
- };
+
+ /*
+ * Creates Pushpin doc and adds it to the list of annotations
+ */
@action
createPushpin = (latitude: number, longitude: number) => {
// Stores the pushpin as a MapMarkerDocument
- const mapMarker = Docs.Create.MapMarkerDocument(NumCast(latitude), NumCast(longitude), false, [], {});
+ const mapMarker = Docs.Create.PushpinDocument(NumCast(latitude), NumCast(longitude), false, [], {});
this.addDocument(mapMarker, this.annotationKey);
- mapMarker.infoWindowOpen = true;
- };
+ // mapMarker.infoWindowOpen = true;
+ };
- selectedPin: Doc | undefined;
- infobox: any;
+ /*
+ * Pushpin onclick
+ */
pushpinClicked = (pin:Doc) => {
- pin["infoWindowOpen"] =
- // true
- !pin.infoWindowOpen;
- // if (this.selectedPin){
- // this.selectedPin.infoWindowOpen = false;
- // this.selectedPin = pin
- // }
- // else{
- // this.selectedPin = pin
- // }
- this.addAllPins();
+ pin.infoWindowOpen = !pin.infoWindowOpen;
+
+ // @action
+ // onPointerDown = (e: React.PointerEvent) => {
+ // if (e.button === 2 || e.ctrlKey) {
+ // AnchorMenu.Instance.Status = 'annotation';
+ // AnchorMenu.Instance.Delete = this.deleteAnnotation.bind(this);
+ // AnchorMenu.Instance.Pinned = false;
+ // AnchorMenu.Instance.PinToPres = this.pinToPres;
+ // AnchorMenu.Instance.MakeTargetToggle = this.makeTargretToggle;
+ // AnchorMenu.Instance.IsTargetToggler = this.isTargetToggler;
+ // AnchorMenu.Instance.ShowTargetTrail = () => this.showTargetTrail(this.annoTextRegion);
+ // AnchorMenu.Instance.jumpTo(e.clientX, e.clientY, true);
+ // e.stopPropagation();
+ // } else if (e.button === 0) {
+ // e.stopPropagation();
+ // LinkFollower.FollowLink(undefined, this.annoTextRegion, false);
+ // }
+ // };
+
+ // TODO: UPDATE FOR DASHDOC SELECTION
};
/**
- * Returns a list of MapMarkerDocument
+ * Returns a list of Pushpin docs
*/
@computed get allMapPushpins() {
return DocListCast(this.dataDoc[this.annotationKey]);
}
+
/**
- * Map OnClick create pushpin
+ * Map OnClick ~> creates a pushpin
*/
@action
mapOnClick = (e: { location: { latitude: any; longitude: any } }) => {
if (this.placePinOn) {
this.createPushpin(e.location.latitude, e.location.longitude);
- this.addAllPins();
+ // this.addAllPins();
this.placePinOn = false;
}
};
+
+
+
+ /*
+ * Updates values of layout doc to match the current map
+ */
+ @action
+ updateLayout = () => {
+ this.dataDoc.latitude = this._bingMap.current.getCenter().latitude;
+ this.dataDoc.longitude = this._bingMap.current.getCenter().longitude;
+ };
+
searched_pin: any;
/*
* For Bing Maps
@@ -651,20 +688,20 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
**/
@action
bingSearch = async () => {
- this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'click', this.mapOnClick);
- this.addAllPins();
-
const location = await this.bingGeocode(this._bingMap, this.bingSearchBarContents);
-
this.dataDoc.latitude = location.latitude;
this.dataDoc.longitude = location.longitude;
- this.updateView();
+ // Centers on the searched location
+ this._bingMap.current.setView({
+ center: new this.MicrosoftMaps.Location(this.dataDoc.latitude, this.dataDoc.longitude),
+ });
+ this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'click', this.mapOnClick);
+ this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'viewchangeend', this.updateLayout);
+
+
// Creates a temporary pin but does not add it to the dataDoc
var temp = new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(location.latitude, location.longitude), {
- // title: this.bingSearchBarContents,
- // subTitle: 'subtitle here',
- // text: '1',
color: 'blue',
});
if (temp != this.searched_pin || this.searched_pin == null) {
@@ -672,82 +709,65 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this.searched_pin = temp;
}
- // console.log(this.allMapPushpins
- // .filter(marker => marker.infoWindowOpen)
- // .length)
- // console.log(this.allMapPushpins
- // .map(marker => console.log(marker.infoWindowOpen)))
};
/**
- * Adds all pushpins in dataDoc onto the map
+ * Adds all pushpins in dataDoc onto the map (render) - OLD & UNUSED
*/
@action
addAllPins = () => {
this._bingMap.current.entities.clear();
if (this.searched_pin) this._bingMap.current.entities.push(this.searched_pin);
-
- this.allMapPushpins.map(pin => this.createPushPin(pin));
-
-
+ // this.allMapPushpins.map(pin => this.addPushpin(pin));
};
- @action
- createPushPin = (pin: any) => {
- var pushPin:any;
- if (pin.infoWindowOpen){
- pushPin = new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(pin.lat, pin.lng), {
- // title: this.bingSearchBarContents,
- // subTitle: 'subtitle here',
- // text: '1',
- // height: '50px'
+ /*
+ * Returns doc w/ relevant info
+ */
+ getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
+ const anchor =
+ Docs.Create.MapanchorDocument({
+ title: 'MapAnchor:' + this.rootDoc.title,
+ presLat: NumCast(this.dataDoc.latitude),
+ presLong: NumCast(this.dataDoc.longitude),
+ // presTransition: 1000,
+ unrendered: true,
+ annotationOn: this.rootDoc,
});
+ if (anchor) {
+ if (!addAsAnnotation) anchor.backgroundColor = 'transparent';
+ /* addAsAnnotation &&*/ this.addDocument(anchor);
+ PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), map: true } }, this.rootDoc);
+ return anchor;
}
- else{
- pushPin = new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(pin.lat, pin.lng), {icon: 'http://icons.iconarchive.com/icons/icons-land/vista-map-markers/24/Map-Marker-Marker-Outside-Chartreuse-icon.png'});
- }
-
- this._bingMap.current.entities.push(pushPin);
-
- var id = Utils.GenerateGuid();
- document.getElementById(id);
- var infoboxTemplate = '<div class="customInfobox"><div class="title">{title}</div>{description}</div>';
- // var infowindowtemp = '<MapBoxInfoWindow key={Docs.Create.MapMarkerDocument(NumCast(40), NumCast(40), false, [], {})[Id]}{...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit} place={Docs.Create.MapMarkerDocument(NumCast(40), NumCast(40), false, [], {})} markerMap={this.markerMap} PanelWidth={this.infoWidth} PanelHeight={this.infoHeight} moveDocument={this.moveDocument} isAnyChildContentActive={this.isAnyChildContentActive} whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}/>'
-
- // console.log(<div id={id} style={{width:100, height:100, background:"blue"}}/>)
- // var htmlString = ReactDOMServer.renderToString(<div id={id} style={{width:100, height:100, background:"blue"}}/>);
-
- //Create an infobox at the pin
- this.infobox = new this.MicrosoftMaps.Infobox(new this.MicrosoftMaps.Location(pin.lat, pin.lng), {
- htmlContent: infoboxTemplate, // style="width:100; height:100; background:blue"
- visible: false,
- });
- try {
- // console.log(document.getElementById(id))
- // console.log(this.infobox)
- // const root = ReactDOM.createRoot(document.getElementById(id)!);
- // root.render(<div style={{width:100, height:100, background:"blue"}}/>);
- } catch (e) {
- console.log(e);
- }
+ return this.rootDoc;
+ };
- //Assign the infobox to a map instance.
- this.infobox.setMap(this._bingMap.current);
- //Store some metadata with the pushpin.
- pushPin.metadata = {
- title: pushPin.title,
- description: 'Pin description',
- };
- // pushPin.infoWindowOpen = true;
+ /*
+ * Input: pin doc
+ * Adds MicrosoftMaps Pushpin to the map (render)
+ */
+ @action
+ addPushpin = (pin: Doc) => {
+ const pushPin = pin.infoWindowOpen ? new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(pin.lat, pin.lng), {}): new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(pin.lat, pin.lng), {icon: 'http://icons.iconarchive.com/icons/icons-land/vista-map-markers/24/Map-Marker-Marker-Outside-Chartreuse-icon.png'});
- //Add a click event handler to the pushpin.
- // For bing maps infobox
- // this.MicrosoftMaps.Events.addHandler(pushPin, 'click', this.pushpinClicked);
+
+ this._bingMap.current.entities.push(pushPin);
// For our infowindow
this.MicrosoftMaps.Events.addHandler(pushPin, 'click', (e: any) => this.pushpinClicked(pin));
- // this.MicrosoftMaps.Events.addHandler(pushPin, 'mouseover', (e:any) => this.onHover(e));
- };
+ }
+
+ /*
+ * Input: pin doc
+ * Adds MicrosoftMaps Pushpin to the map (render)
+ */
+ @action
+ removePushpin = (pin:any)=>{
+ this._bingMap.current.entities.clear();
+ this.allMapPushpins
+ this.allMapPushpins.map(pin => this.addPushpin(pin));
+ }
/**
* View options for bing maps
@@ -809,25 +829,37 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
{this.placePinOn ? <input type="button" value="Place Pin Mode On" onClick={this.togglePlacePin} /> : <input type="button" value="Place Pin Mode Off" onClick={this.togglePlacePin} />}
<BingMapsReact onMapReady={this.bingMapReady} bingMapsKey={bingApiKey} height="100%" mapOptions={this.bingMapOptions} width="100%" viewOptions={this.bingViewOptions}>
+ </BingMapsReact>
+ <div>
{this.allMapPushpins
- .filter(marker => marker.infoWindowOpen)
- .map(marker => (
- // console.log('this is a marker window')
- <MapBoxInfoWindow
- key={marker[Id]}
+ .map(pushpin => (
+ <DocumentView
{...this.props}
- setContentView={emptyFunction}
- place={marker}
- markerMap={this.markerMap}
- PanelWidth={this.infoWidth}
- PanelHeight={this.infoHeight}
- moveDocument={this.moveDocument}
- isAnyChildContentActive={this.isAnyChildContentActive}
- whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
- />
+
+ // HOW DO I PASS IN pushpin???
+ // HOW DO I MAKE SURE IT KNOWS TO MAKE MapPushpinBox???
+ Document={pushpin}
+ DataDoc={undefined}
+ PanelWidth={returnOne}
+ PanelHeight={returnOne}
+ NativeWidth={returnOne}
+ NativeHeight={returnOne}
+ onClick={()=>new ScriptField(undefined)}
+ onKey={undefined}
+ onDoubleClick={undefined}
+ onBrowseClick={undefined}
+ docFilters={returnEmptyDoclist}
+ docRangeFilters={returnEmptyDoclist}
+ searchFilterDocs={returnEmptyDoclist}
+ isDocumentActive={returnFalse}
+ isContentActive={returnFalse}
+ addDocTab={returnFalse}
+ ScreenToLocalTransform={()=>new Transform(0,0,0)}
+ fitContentsToBox={undefined}
+ focus={returnOne}
+ />
))}
- </BingMapsReact>
-
+ </div>
{/* <MapBoxInfoWindow
key={Docs.Create.MapMarkerDocument(NumCast(40), NumCast(40), false, [], {})[Id]}
{...OmitKeys(this.props, ['NativeWidth', 'NativeHeight', 'setContentView']).omit}