From 9d48c95e5a556f5be4abde83d9443e384a33197c Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 10 Jul 2023 14:26:37 -0400 Subject: Location metadata synced and reactions working --- src/client/views/nodes/MapBox/MapPushpinBox.tsx | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/client/views/nodes/MapBox/MapPushpinBox.tsx (limited to 'src/client/views/nodes/MapBox/MapPushpinBox.tsx') diff --git a/src/client/views/nodes/MapBox/MapPushpinBox.tsx b/src/client/views/nodes/MapBox/MapPushpinBox.tsx new file mode 100644 index 000000000..13fb11054 --- /dev/null +++ b/src/client/views/nodes/MapBox/MapPushpinBox.tsx @@ -0,0 +1,38 @@ +import { observer } from 'mobx-react'; +// import { SettingsManager } from '../../../util/SettingsManager'; +import { ViewBoxBaseComponent } from '../../DocComponent'; +import { FieldView, FieldViewProps } from '../FieldView'; +import React = require('react'); +import { computed } from 'mobx'; +import { MapBox } from './MapBox'; + + +/** + * Map Pushpin doc class + */ +@observer +export class MapPushpinBox extends ViewBoxBaseComponent() { + + + public static LayoutString(fieldKey: string) { + return FieldView.LayoutString(MapPushpinBox, fieldKey); + } + componentDidMount() { + this.mapBoxView.addPushpin(this.rootDoc); + } + componentWillUnmount() { + this.mapBoxView.removePushpin(this.rootDoc); + } + + + @computed get mapBoxView() { + return this.props.DocumentView?.()?.props.docViewPath().lastElement()?.ComponentView as MapBox; + } + @computed get mapBox() { + return this.props.DocumentView?.().props.docViewPath().lastElement()?.rootDoc; + } + + render() { + return (
); + } +} -- cgit v1.2.3-70-g09d2 From c059bdf0b2707181b4c6b7bf626f99ac33a81b58 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 1 Aug 2023 13:40:37 -0400 Subject: Pin onclick remove fully integrate, working but not tested a lot --- src/client/views/nodes/MapBox/MapBox.tsx | 67 +++++++++++++++++++------ src/client/views/nodes/MapBox/MapPushpinBox.tsx | 2 +- 2 files changed, 52 insertions(+), 17 deletions(-) (limited to 'src/client/views/nodes/MapBox/MapPushpinBox.tsx') diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 8e460c090..02fa31d9e 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -140,11 +140,36 @@ export class MapBox extends ViewBoxAnnotatableComponent ({pinList:this.dataDoc[this.annotationKey]}), + // (pinsObject) => { + // this._bingMap.current.entities.clear(); + // pinsObject.pinList.map((pushpin: Doc) => ( + // 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} + // />)); + + // }, {fireImmediately: false}); } @@ -615,15 +640,16 @@ export class MapBox extends ViewBoxAnnotatableComponent { // Stores the pushpin as a MapMarkerDocument - const mapMarker = Docs.Create.PushpinDocument(NumCast(latitude), NumCast(longitude), false, [], {}); + const mapMarker = Docs.Create.PushpinDocument(NumCast(latitude), NumCast(longitude), false, [], {},'pushpinIDamongus'+this.incrementer); this.addDocument(mapMarker, this.annotationKey); + this.incrementer++; // mapMarker.infoWindowOpen = true; }; @@ -631,15 +657,20 @@ export class MapBox extends ViewBoxAnnotatableComponent { - pin.infoWindowOpen = !pin.infoWindowOpen; - + @action + pushpinClicked = (pinDoc:Doc,pin:any) => { // TODO: // if (sidebarannos is not open) open sidebarannos + // creates button onclick removes the doc from annotations // pan to pushpin location - this.dataDoc.latitude = pin.lat; - this.dataDoc.longitude = pin.lng; + this.dataDoc.latitude = pinDoc.lat; + this.dataDoc.longitude = pinDoc.lng; + // this.dataDoc[this.annotationKey].pop(pin); + this.removePushpin(pinDoc,pin); + + + // @action @@ -792,19 +823,22 @@ export class MapBox extends ViewBoxAnnotatableComponent this.pushpinClicked(pin)); + this.MicrosoftMaps.Events.addHandler(pushPin, 'click', (e: any) => this.pushpinClicked(pin,pushPin)); } /* * Input: pin doc - * Adds MicrosoftMaps Pushpin to the map (render) + * Removes MicrosoftMaps Pushpin to the map (render) */ @action - removePushpin = (pin:any)=>{ - // this._bingMap.current.entities.clear(); + removePushpin = (pinDoc:Doc,pin:any)=>{ // this.allMapPushpins - this.allMapPushpins.map(pin => this.addPushpin(pin)); + // this.allMapPushpins.map(pin => this.addPushpin(pin)); + // this._bingMap.current.entities.clear(); + this._bingMap.current.entities.remove(pin); + this.removeDocument(pinDoc, this.annotationKey); + + // this.dataDoc[this.annotationKey] } /** @@ -889,6 +923,7 @@ export class MapBox extends ViewBoxAnnotatableComponent
+ {this.allMapPushpins .map(pushpin => ( () { this.mapBoxView.addPushpin(this.rootDoc); } componentWillUnmount() { - this.mapBoxView.removePushpin(this.rootDoc); + // this.mapBoxView.removePushpin(this.rootDoc); } -- cgit v1.2.3-70-g09d2 From eb35837e5ffe8e7eba9decea1fae5c163528dc1e Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 21 Aug 2023 11:59:05 -0400 Subject: Buggy --- src/client/documents/Documents.ts | 5 +- src/client/views/nodes/MapBox/MapBox.scss | 4 + src/client/views/nodes/MapBox/MapBox.tsx | 201 +++++++++++++----------- src/client/views/nodes/MapBox/MapPushpinBox.tsx | 4 +- src/client/views/nodes/trails/PresBox.tsx | 5 +- 5 files changed, 120 insertions(+), 99 deletions(-) (limited to 'src/client/views/nodes/MapBox/MapPushpinBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index af4cf2243..eb777aae2 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -368,8 +368,6 @@ export class DocumentOptions { waitForDoubleClickToClick?: 'always' | 'never' | 'default'; // whether a click function wait for double click to expire. 'default' undefined = wait only if there's a click handler, "never" = never wait, "always" = alway wait onPointerDown?: ScriptField; onPointerUp?: ScriptField; - openFactoryLocation?: string; // an OpenWhere value to place the factory created document - openFactoryAsDelegate?: BOOLt = new BoolInfo('create a delegate of the factory'); _forceActive?: BOOLt = new BoolInfo('flag to handle pointer events when not selected (or otherwise active)'); _dragOnlyWithinContainer?: BOOLt = new BoolInfo('whether the document should remain in its collection when someone tries to drag and drop it elsewhere'); _raiseWhenDragged?: BOOLt = new BoolInfo('whether a document is brought to front when dragged.'); @@ -381,7 +379,6 @@ export class DocumentOptions { cloneFieldFilter?: List; // fields not to copy when the document is clonedclipboard?: Doc; dragWhenActive?: BOOLt = new BoolInfo('should document drag when it is active - e.g., pileView, group'); dragAction?: DROPt = new DAInfo('how to drag document when it is active (e.g., tree, groups)'); - dragFactory_count?: NUMt = new NumInfo('number of items created from a drag button (used for setting title with incrementing index)', true); dragFactory?: Doc; // document to create when dragging with a suitable onDragStart script clickFactory?: Doc; // document to create when clicking on a button with a suitable onClick script onDragStart?: ScriptField; //script to execute at start of drag operation -- e.g., when a "creator" button is dragged this script generates a different document to drop @@ -1104,7 +1101,7 @@ export namespace Docs { ); } export function MapanchorDocument(options: DocumentOptions = {}, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.MARKER), options?.data, options, id); + return InstanceFromProto(Prototypes.get(DocumentType.MAP), options?.data, options, id); } export function LinearDocument(documents: Array, options: DocumentOptions, id?: string) { diff --git a/src/client/views/nodes/MapBox/MapBox.scss b/src/client/views/nodes/MapBox/MapBox.scss index fcd4fc9be..39fa3262e 100644 --- a/src/client/views/nodes/MapBox/MapBox.scss +++ b/src/client/views/nodes/MapBox/MapBox.scss @@ -11,6 +11,10 @@ padding: 12; font-size: 17; } + .mapBox-searchbar{ + display:flex; + flex-direction: row; + } .mapBox-topbar{ display:flex; flex-direction: row; diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 283d57bb6..bad1a3ebd 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -1,7 +1,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { GoogleMapProps, Marker } from '@react-google-maps/api'; import BingMapsReact from 'bingmaps-react'; -import { EditableText, Toggle } from 'browndash-components'; +import { EditableText, IconButton, Toggle, Type } from 'browndash-components'; import e from 'connect-flash'; import { truncateSync } from 'fs'; import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx'; @@ -13,12 +13,12 @@ import { Id } from '../../../../fields/FieldSymbols'; import { InkTool } from '../../../../fields/InkField'; import { ScriptField } from '../../../../fields/ScriptField'; import { NumCast, StrCast } from '../../../../fields/Types'; -import { emptyFunction, returnAll, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils'; +import { emptyFunction, returnAll, returnEmptyDoclist, returnEmptyFilter, 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 { undoable, UndoManager } from '../../../util/UndoManager'; import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm'; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent'; import { Colors } from '../../global/globalEnums'; @@ -116,7 +116,7 @@ export class MapBox extends ViewBoxAnnotatableComponent(); @observable private searchMarkers: google.maps.Marker[] = []; - // @observable private searchBox = new window.google.maps.places.Autocomplete(this.inputRef.current!, options); + @observable private searchBox = undefined as any; // new window.google.maps.places.Autocomplete(this.inputRef.current!, options); @observable private _savedAnnotations = new ObservableMap(); @computed get allSidebarDocs() { return DocListCast(this.dataDoc[this.SidebarKey]); @@ -138,45 +138,6 @@ export class MapBox extends ViewBoxAnnotatableComponent = React.createRef(); private _disposer: {[key:string]:IReactionDisposer} = {} componentDidMount() { - this.props.setContentView?.(this); - this._disposer.location = reaction(() => ({lat:this.rootDoc.latitude, lng:this.rootDoc.longitude, zoom:this.rootDoc.zoom,mapType:this.rootDoc.mapType}), - (locationObject) => { - - this._bingMap.current.setView({ - mapTypeId: locationObject.mapType, - zoom:locationObject.zoom, - center: new this.MicrosoftMaps.Location(locationObject.lat, locationObject.lng), - }); - - }, {fireImmediately: true}); - // this._disposer.pins = reaction(() => ({pinList:this.dataDoc[this.annotationKey]}), - // (pinsObject) => { - // this._bingMap.current.entities.clear(); - // pinsObject.pinList.map((pushpin: Doc) => ( - // 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} - // />)); - - // }, {fireImmediately: false}); } @@ -638,7 +599,7 @@ export class MapBox extends ViewBoxAnnotatableComponent { + pushpinClicked = (pinDoc:Doc) => { // TODO: // if (sidebarannos is not open) open sidebarannos // creates button onclick removes the doc from annotations @@ -685,27 +646,6 @@ export class MapBox extends ViewBoxAnnotatableComponent { - // 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 }; /** @@ -811,10 +751,10 @@ export class MapBox extends ViewBoxAnnotatableComponent this.pushpinClicked(pin,pushPin)); + this.MicrosoftMaps.Events.addHandler(pushPin, 'click', (e: any) => this.pushpinClicked(pin)); this.MicrosoftMaps.Events.addHandler(pushPin, 'dblclick', (e: any) => this.pushpinDblClicked(pushPin, pin)); } @@ -876,7 +816,7 @@ export class MapBox extends ViewBoxAnnotatableComponent{ + this.bingSearchBarContents = newText + } + /* * Called when BingMap is first rendered * Initializes starting values */ bingMapReady = (map: any) => { this._bingMap = map.map; - this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'click', this.mapOnClick); - this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'viewchangeend', this.updateLayout); - this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'maptypechanged', this.updateMapType); - this.updateLayout(); - this.updateMapType(); + if (!this._bingMap.current) { + alert("NO Map!?") + } + this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'click', undoable(this.mapOnClick, "Added Pin to Map")); + this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'viewchangeend', undoable(this.updateLayout, "Map Layout Change")); + this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'maptypechanged', undoable(this.updateMapType, "Map ViewType Change")); + //this.updateLayout(); + // this.updateMapType(); + this.props.setContentView?.(this); + this._disposer.location = reaction(() => ({lat:this.rootDoc.latitude, lng:this.rootDoc.longitude, zoom:this.rootDoc.zoom,mapType:this.rootDoc.mapType}), + (locationObject) => { + // if (this._bingMap.current) + this._bingMap.current?.setView({ + mapTypeId: locationObject.mapType, + zoom:locationObject.zoom, + center: new this.MicrosoftMaps.Location(locationObject.lat, locationObject.lng), + }); + + }, {fireImmediately: true}); + // this._disposer.pins = reaction(() => ({pinList:this.dataDoc[this.annotationKey]}), + // (pinsObject) => { + // this._bingMap.current.entities.clear(); + // pinsObject.pinList.map((pushpin: Doc) => ( + // 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} + // />)); + + // }, {fireImmediately: false}); + } + searchbarKeyDown = (e:any)=>{ + if (e.key === 'Enter') { + this.bingSearch() + } + } - render() { const renderAnnotations = (childFilters?: () => string[]) => null; return ( @@ -937,9 +929,44 @@ export class MapBox extends ViewBoxAnnotatableComponent ({})} editing onEdit={(newText: string) => (this.bingSearchBarContents = newText)} placeholder="Boston, MA" text="Boston, MA" /> + +
+ typeof newText === "string" && this.searchbarOnEdit(newText)} + placeholder="Boston" + // text="text" + /> +
+ +
- + {/* */} + {/* {this.placePinOn ? : } */} {/* {this.placePinOn ? : } @@ -957,19 +984,7 @@ export class MapBox extends ViewBoxAnnotatableComponent */} - - - +
@@ -992,8 +1007,8 @@ export class MapBox extends ViewBoxAnnotatableComponent() { return FieldView.LayoutString(MapPushpinBox, fieldKey); } componentDidMount() { - this.mapBoxView.addPushpin(this.rootDoc); + // if (this.mapBoxView) + this.mapBoxView.addPushpin(this.rootDoc); } componentWillUnmount() { // this.mapBoxView.removePushpin(this.rootDoc); diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 76f42778b..1560ce3e1 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -659,7 +659,10 @@ export class PresBox extends ViewBoxBaseComponent() { pinDoc.presYRange = undefined; //targetDoc?.yrange; } if (pinProps.pinData.map) { - pinDoc.presLat = targetDoc?.lat; + pinDoc.presLat = targetDoc?.latitude; + pinDoc.presLong = targetDoc?.longitude; + pinDoc.presZoom = targetDoc?.zoom; + pinDoc.mapType = targetDoc?.mapType; //... } if (pinProps.pinData.poslayoutview) -- cgit v1.2.3-70-g09d2 From 565d4c98628f547ba27e2d9c74138602c8cbd7a5 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 21 Aug 2023 12:40:39 -0400 Subject: fixed calling setComponentView for maps --- src/client/views/nodes/MapBox/MapBox.tsx | 147 ++---------------------- src/client/views/nodes/MapBox/MapPushpinBox.tsx | 9 +- 2 files changed, 12 insertions(+), 144 deletions(-) (limited to 'src/client/views/nodes/MapBox/MapPushpinBox.tsx') diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 50d1aa9d6..860528ec4 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -1,9 +1,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { GoogleMapProps, Marker } from '@react-google-maps/api'; import BingMapsReact from 'bingmaps-react'; -import { EditableText, IconButton, Toggle, Type } from 'browndash-components'; -import e from 'connect-flash'; -import { truncateSync } from 'fs'; +import { EditableText, IconButton, Type } from 'browndash-components'; import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -13,7 +11,7 @@ import { Id } from '../../../../fields/FieldSymbols'; import { InkTool } from '../../../../fields/InkField'; import { ScriptField } from '../../../../fields/ScriptField'; import { NumCast, StrCast } from '../../../../fields/Types'; -import { emptyFunction, returnAll, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnIgnore, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils'; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils'; import { Docs } from '../../../documents/Documents'; import { DragManager } from '../../../util/DragManager'; import { SnappingManager } from '../../../util/SnappingManager'; @@ -23,14 +21,12 @@ import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm'; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent'; import { Colors } from '../../global/globalEnums'; 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, PresBox } from '../trails'; import './MapBox.scss'; -import { MapBoxInfoWindow } from './MapBoxInfoWindow'; // amongus /** * MapBox architecture: @@ -62,11 +58,11 @@ const mapOptions = { const bingApiKey = process.env.BING_MAPS; // if you're running local, get a Bing Maps api key here: https://www.bingmapsportal.com/ and then add it to the .env file in the Dash-Web root directory as: _CLIENT_BING_MAPS= -const script = document.createElement('script'); -script.defer = true; -script.async = true; -script.src = `https://maps.googleapis.com/maps/api/js?key=${bingApiKey}&libraries=places,drawing`; -document.head.appendChild(script); +// const script = document.createElement('script'); +// script.defer = true; +// script.async = true; +// script.src = `https://maps.googleapis.com/maps/api/js?key=${bingApiKey}&libraries=places,drawing`; +// document.head.appendChild(script); /** * Consider integrating later: allows for drawing, circling, making shapes on map @@ -84,13 +80,6 @@ document.head.appendChild(script); // }, // }); -// options for searchbox in Google Maps Places Autocomplete API -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 class MapBox extends ViewBoxAnnotatableComponent>() { private _dropDisposer?: DragManager.DragDropDisposer; @@ -137,7 +126,9 @@ export class MapBox extends ViewBoxAnnotatableComponent(); private _ref: React.RefObject = React.createRef(); private _disposer: { [key: string]: IReactionDisposer } = {}; - componentDidMount() {} + componentDidMount() { + this.props.setContentView?.(this); + } componentWillUnmount(): void { Object.keys(this._disposer).forEach(key => this._disposer[key]?.()); @@ -149,74 +140,6 @@ export class MapBox extends ViewBoxAnnotatableComponent bounds.extend({ lat: NumCast(place.lat), lng: NumCast(place.lng) }), new window.google.maps.LatLngBounds())); }; - /** - * Custom control for add marker button - * @param controlDiv - * @param map - */ - private CenterControl = () => { - const controlDiv = document.createElement('div'); - controlDiv.className = 'mapBox-addMarker'; - // Set CSS for the control border. - const controlUI = document.createElement('div'); - controlUI.style.backgroundColor = '#fff'; - controlUI.style.borderRadius = '3px'; - controlUI.style.cursor = 'pointer'; - controlUI.style.marginTop = '10px'; - controlUI.style.borderRadius = '4px'; - controlUI.style.marginBottom = '22px'; - controlUI.style.textAlign = 'center'; - controlUI.style.position = 'absolute'; - controlUI.style.width = '32px'; - controlUI.style.height = '32px'; - controlUI.title = 'Click to toggle marker mode. In marker mode, click on map to place a marker.'; - - const plIcon = document.createElement('img'); - plIcon.src = 'https://cdn4.iconfinder.com/data/icons/wirecons-free-vector-icons/32/add-256.png'; - plIcon.style.color = 'rgb(25,25,25)'; - plIcon.style.fontFamily = 'Roboto,Arial,sans-serif'; - plIcon.style.fontSize = '16px'; - plIcon.style.lineHeight = '32px'; - plIcon.style.left = '18'; - plIcon.style.top = '15'; - plIcon.style.position = 'absolute'; - plIcon.width = 14; - plIcon.height = 14; - plIcon.innerHTML = 'Add'; - controlUI.appendChild(plIcon); - - // Set CSS for the control interior. - const markerIcon = document.createElement('img'); - markerIcon.src = 'https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678111-map-marker-1024.png'; - markerIcon.style.color = 'rgb(25,25,25)'; - markerIcon.style.fontFamily = 'Roboto,Arial,sans-serif'; - markerIcon.style.fontSize = '16px'; - markerIcon.style.lineHeight = '32px'; - markerIcon.style.left = '-2'; - markerIcon.style.top = '1'; - markerIcon.width = 30; - markerIcon.height = 30; - markerIcon.style.position = 'absolute'; - markerIcon.innerHTML = 'Add'; - controlUI.appendChild(markerIcon); - - // Setup the click event listeners - controlUI.addEventListener('click', () => { - if (this.toggleAddMarker === true) { - this.toggleAddMarker = false; - console.log('add marker button status:' + this.toggleAddMarker); - controlUI.style.backgroundColor = '#fff'; - markerIcon.style.color = 'rgb(25,25,25)'; - } else { - this.toggleAddMarker = true; - console.log('add marker button status:' + this.toggleAddMarker); - controlUI.style.backgroundColor = '#4476f7'; - markerIcon.style.color = 'rgb(255,255,255)'; - } - }); - controlDiv.appendChild(controlUI); - return controlDiv; - }; /** * Load and render all map markers * @param marker @@ -256,47 +179,6 @@ export class MapBox extends ViewBoxAnnotatableComponent { - this._map = map; - this._loadPending = true; - const centerControlDiv = this.CenterControl(); - map.controls[google.maps.ControlPosition.TOP_RIGHT].push(centerControlDiv); - //drawingManager.setMap(map); - // if (navigator.geolocation) { - // navigator.geolocation.getCurrentPosition( - // (position: Position) => { - // const pos = { - // lat: position.coords.latitude, - // lng: position.coords.longitude, - // }; - // this._map.setCenter(pos); - // } - // ); - // } else { - // alert("Your geolocation is not supported by browser.") - // }; - map.setZoom(NumCast(this.dataDoc.mapZoom, 2.5)); - map.setCenter(new google.maps.LatLng(NumCast(this.dataDoc.mapLat), NumCast(this.dataDoc.mapLng))); - setTimeout(() => { - if (this._loadPending && this._map.getBounds()) { - this._loadPending = false; - this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map); - } - }, 250); - // listener to addmarker event - this._map.addListener('click', (e: MouseEvent) => { - if (this.toggleAddMarker === true) { - this.placeMarker((e as any).latLng, map); - } - }); - }; @action centered = () => { @@ -535,14 +417,6 @@ export class MapBox extends ViewBoxAnnotatableComponent { - // console.log("print the selected views in selectionManager:") - // if (SelectionManager.Views().lastElement()) { - // console.log(SelectionManager.Views().lastElement()); - // } - }; - panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth(); panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1); scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); @@ -847,7 +721,6 @@ export class MapBox extends ViewBoxAnnotatableComponent ({ lat: this.rootDoc.latitude, lng: this.rootDoc.longitude, zoom: this.rootDoc.mapZoom, mapType: this.rootDoc.mapType }), locationObject => { diff --git a/src/client/views/nodes/MapBox/MapPushpinBox.tsx b/src/client/views/nodes/MapBox/MapPushpinBox.tsx index 6369f9e04..d28209ea1 100644 --- a/src/client/views/nodes/MapBox/MapPushpinBox.tsx +++ b/src/client/views/nodes/MapBox/MapPushpinBox.tsx @@ -5,28 +5,23 @@ import { FieldView, FieldViewProps } from '../FieldView'; import React = require('react'); import { computed } from 'mobx'; import { MapBox } from './MapBox'; -import { undoable } from '../../../util/UndoManager'; - /** * Map Pushpin doc class */ @observer export class MapPushpinBox extends ViewBoxBaseComponent() { - - public static LayoutString(fieldKey: string) { return FieldView.LayoutString(MapPushpinBox, fieldKey); } componentDidMount() { // if (this.mapBoxView) - this.mapBoxView.addPushpin(this.rootDoc); + this.mapBoxView.addPushpin(this.rootDoc); } componentWillUnmount() { // this.mapBoxView.removePushpin(this.rootDoc); } - @computed get mapBoxView() { return this.props.DocumentView?.()?.props.docViewPath().lastElement()?.ComponentView as MapBox; } @@ -35,6 +30,6 @@ export class MapPushpinBox extends ViewBoxBaseComponent() { } render() { - return (
); + return
; } } -- cgit v1.2.3-70-g09d2 From e724cf830b773d22bada7c319f5c2527b2ffeae7 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 22 Aug 2023 16:31:00 -0400 Subject: Everything working, except for offset of placing pins and mapanchormenu when sidebar is open --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/MainView.tsx | 2 + src/client/views/nodes/MapBox/MapAnchorMenu.tsx | 355 ++++-------------------- src/client/views/nodes/MapBox/MapBox.tsx | 162 +++++++---- src/client/views/nodes/MapBox/MapPushpinBox.tsx | 2 +- 5 files changed, 168 insertions(+), 355 deletions(-) (limited to 'src/client/views/nodes/MapBox/MapPushpinBox.tsx') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 25c8f511b..b63d501de 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -272,7 +272,7 @@ export class CurrentUserUtils { {key: "Webpage", creator: opts => Docs.Create.WebDocument("",opts), opts: { _width: 400, _height: 512, _nativeWidth: 850, data_useCors: true, }}, {key: "Comparison", creator: Docs.Create.ComparisonDocument, opts: { _width: 300, _height: 300 }}, {key: "Audio", creator: opts => Docs.Create.AudioDocument(nullAudio, opts),opts: { _width: 200, _height: 100, }}, - {key: "Map", creator: opts => Docs.Create.MapDocument([], opts), opts: { _width: 800, _height: 600, _layout_fitWidth: true, _layout_showSidebar: true, }}, + {key: "Map", creator: opts => Docs.Create.MapDocument([], opts), opts: { _width: 800, _height: 600, _layout_fitWidth: true, }}, {key: "Screengrab", creator: Docs.Create.ScreenshotDocument, opts: { _width: 400, _height: 200 }}, {key: "WebCam", creator: opts => Docs.Create.WebCamDocument("", opts), opts: { _width: 400, _height: 200, recording:true, isSystem: true, cloneFieldFilter: new List(["isSystem"]) }}, {key: "Button", creator: Docs.Create.ButtonDocument, opts: { _width: 150, _height: 50, _xPadding: 10, _yPadding: 10}, scripts: {onClick: FollowLinkScript()?.script.originalScript ?? ""}}, diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index e376c4fdf..b088157e5 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -57,6 +57,7 @@ import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { RichTextMenu } from './nodes/formattedText/RichTextMenu'; import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup'; import { LinkDocPreview } from './nodes/LinkDocPreview'; +import { MapAnchorMenu } from './nodes/MapBox/MapAnchorMenu'; import { RadialMenu } from './nodes/RadialMenu'; import { TaskCompletionBox } from './nodes/TaskCompletedBox'; import { OverlayView } from './OverlayView'; @@ -1004,6 +1005,7 @@ export class MainView extends React.Component { + diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx index 798905bcd..439c1f14f 100644 --- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx +++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx @@ -3,18 +3,18 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, IReactionDisposer, observable, ObservableMap, reaction } from 'mobx'; import { observer } from 'mobx-react'; import { ColorState } from 'react-color'; -import { Doc, Opt } from '../../../fields/Doc'; -import { returnFalse, setupMoveUpEvents, unimplementedFunction, Utils } from '../../../Utils'; -import { SelectionManager } from '../../util/SelectionManager'; -import { AntimodeMenu, AntimodeMenuProps } from "../AntimodeMenu" -import { LinkPopup } from '../linking/LinkPopup'; -import { gptAPICall, GPTCallType } from '../../apis/gpt/GPT'; -import { GPTPopup, GPTPopupMode } from './GPTPopup/GPTPopup'; +import { Doc, Opt } from '../../../../fields/Doc'; +import { returnFalse, setupMoveUpEvents, unimplementedFunction, Utils } from '../../../../Utils'; +import { SelectionManager } from '../../../util/SelectionManager'; +import { AntimodeMenu, AntimodeMenuProps } from "../../AntimodeMenu" +import { LinkPopup } from '../../linking/LinkPopup'; +import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT'; +// import { GPTPopup, GPTPopupMode } from './../../GPTPopup/GPTPopup'; import { EditorView } from 'prosemirror-view'; import './MapAnchorMenu.scss'; import { ColorPicker, Group, IconButton, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components'; -import { StrCast } from '../../../fields/Types'; -import { DocumentType } from '../../documents/DocumentTypes'; +import { StrCast } from '../../../../fields/Types'; +import { DocumentType } from '../../../documents/DocumentTypes'; @observer export class MapAnchorMenu extends AntimodeMenu { @@ -24,73 +24,22 @@ export class MapAnchorMenu extends AntimodeMenu { private _disposer2: IReactionDisposer | undefined; private _commentCont = React.createRef(); - @observable private highlightColor: string = 'rgba(245, 230, 95, 0.616)'; - @observable public Status: 'marquee' | 'annotation' | '' = ''; - // GPT additions - @observable private GPTpopupText: string = ''; - @observable private loadingGPT: boolean = false; - @observable private showGPTPopup: boolean = false; - @observable private GPTMode: GPTPopupMode = GPTPopupMode.SUMMARY; - @observable private selectedText: string = ''; - @observable private editorView?: EditorView; - @observable private textDoc?: Doc; - @observable private highlightRange: number[] | undefined; - private selectionRange: number[] | undefined; - - @action - setGPTPopupVis = (vis: boolean) => { - this.showGPTPopup = vis; - }; - @action - setGPTMode = (mode: GPTPopupMode) => { - this.GPTMode = mode; - }; - - @action - setGPTPopupText = (txt: string) => { - this.GPTpopupText = txt; - }; - - @action - setLoading = (loading: boolean) => { - this.loadingGPT = loading; - }; - - @action - setHighlightRange(r: number[] | undefined) { - this.highlightRange = r; - } - - @action - public setSelectedText = (txt: string) => { - this.selectedText = txt; - }; - - @action - public setEditorView = (editor: EditorView) => { - this.editorView = editor; - }; - - @action - public setTextDoc = (textDoc: Doc) => { - this.textDoc = textDoc; - }; public onMakeAnchor: () => Opt = () => undefined; // Method to get anchor from text search - public OnCrop: (e: PointerEvent) => void = unimplementedFunction; - public OnClick: (e: PointerEvent) => void = unimplementedFunction; - public OnAudio: (e: PointerEvent) => void = unimplementedFunction; - public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction; - public StartCropDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction; + public Center: () => void = unimplementedFunction; + // public OnClick: (e: PointerEvent) => void = unimplementedFunction; + // public OnAudio: (e: PointerEvent) => void = unimplementedFunction; + // public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction; + // public StartCropDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction; public Highlight: (color: string, isTargetToggler: boolean, savedAnnotations?: ObservableMap, addAsAnnotation?: boolean) => Opt = (color: string, isTargetToggler: boolean) => undefined; public GetAnchor: (savedAnnotations: Opt>, addAsAnnotation: boolean) => Opt = (savedAnnotations: Opt>, addAsAnnotation: boolean) => undefined; public Delete: () => void = unimplementedFunction; - public PinToPres: () => void = unimplementedFunction; - public MakeTargetToggle: () => void = unimplementedFunction; - public ShowTargetTrail: () => void = unimplementedFunction; + public LinkNote: () => void = unimplementedFunction; + // public MakeTargetToggle: () => void = unimplementedFunction; + // public ShowTargetTrail: () => void = unimplementedFunction; public IsTargetToggler: () => boolean = returnFalse; public get Active() { return this._left > 0; @@ -113,8 +62,6 @@ export class MapAnchorMenu extends AntimodeMenu { () => this._opacity, opacity => { if (!opacity) { - this.setGPTPopupVis(false); - this.setGPTPopupText(''); } }, { fireImmediately: true } @@ -122,259 +69,62 @@ export class MapAnchorMenu extends AntimodeMenu { this._disposer = reaction( () => SelectionManager.Views().slice(), selected => { - this.setGPTPopupVis(false); - this.setGPTPopupText(''); MapAnchorMenu.Instance.fadeOut(true); } ); } + // audioDown = (e: React.PointerEvent) => { + // setupMoveUpEvents(this, e, returnFalse, returnFalse, e => this.OnAudio?.(e)); + // }; + + // cropDown = (e: React.PointerEvent) => { + // setupMoveUpEvents( + // this, + // e, + // (e: PointerEvent) => { + // this.StartCropDrag(e, this._commentCont.current!); + // return true; + // }, + // returnFalse, + // e => this.OnCrop?.(e) + // ); + // }; + + + static top = React.createRef(); + // public get Top(){ + // return this.top + // } - /** - * Invokes the API with the selected text and stores it in the summarized text. - * @param e pointer down event - */ - gptSummarize = async (e: React.PointerEvent) => { - this.setHighlightRange(undefined); - this.setGPTPopupVis(true); - this.setGPTMode(GPTPopupMode.SUMMARY); - this.setLoading(true); - - try { - const res = await gptAPICall(this.selectedText, GPTCallType.SUMMARY); - if (res) { - this.setGPTPopupText(res); - } else { - this.setGPTPopupText('Something went wrong.'); - } - } catch (err) { - console.error(err); - } - - this.setLoading(false); - }; - - /** - * Makes a GPT call to edit selected text. - * @returns nothing - */ - gptEdit = async () => { - if (!this.editorView) return; - this.setHighlightRange(undefined); - const state = this.editorView.state; - const sel = state.selection; - const fullText = state.doc.textBetween(0, this.editorView.state.doc.content.size, ' \n'); - const selectedText = state.doc.textBetween(sel.from, sel.to); - - this.setGPTPopupVis(true); - this.setGPTMode(GPTPopupMode.EDIT); - this.setLoading(true); - - try { - let res = await gptAPICall(selectedText, GPTCallType.EDIT); - // let res = await this.mockGPTCall(); - if (!res) return; - res = res.trim(); - const resultText = fullText.slice(0, sel.from - 1) + res + fullText.slice(sel.to - 1); - - if (res) { - this.setGPTPopupText(resultText); - this.setHighlightRange([sel.from - 1, sel.from - 1 + res.length]); - } else { - this.setGPTPopupText('Something went wrong.'); - } - } catch (err) { - console.error(err); - } - - this.setLoading(false); - }; - - /** - * Replaces text suggestions from GPT. - */ - replaceText = (replacement: string) => { - if (!this.editorView || !this.textDoc) return; - this.textDoc.text = replacement; - }; - - pointerDown = (e: React.PointerEvent) => { - setupMoveUpEvents( - this, - e, - (e: PointerEvent) => { - this.StartDrag(e, this._commentCont.current!); - return true; - }, - returnFalse, - e => this.OnClick?.(e) - ); - }; - - audioDown = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, returnFalse, returnFalse, e => this.OnAudio?.(e)); - }; - - cropDown = (e: React.PointerEvent) => { - setupMoveUpEvents( - this, - e, - (e: PointerEvent) => { - this.StartCropDrag(e, this._commentCont.current!); - return true; - }, - returnFalse, - e => this.OnCrop?.(e) - ); - }; - - @action - highlightClicked = (e: React.MouseEvent) => { - this.Highlight(this.highlightColor, false, undefined, true); - MapAnchorMenu.Instance.fadeOut(true); - }; - - @computed get highlighter() { - return ( - - } - tooltip={'Click to Highlight'} - onClick={this.highlightClicked} - colorPicker={this.highlightColor} - color={StrCast(Doc.UserDoc().userColor)} - /> - - - ); - } - - @action changeHighlightColor = (color: string) => { - const col: ColorState = { - hex: color, - hsl: { a: 0, h: 0, s: 0, l: 0, source: '' }, - hsv: { a: 0, h: 0, s: 0, v: 0, source: '' }, - rgb: { a: 0, r: 0, b: 0, g: 0, source: '' }, - oldHue: 0, - source: '', - }; - this.highlightColor = Utils.colorString(col); - }; - - /** - * Returns whether the selected text can be summarized. The goal is to have - * all selected text available to summarize but its only supported for pdf and web ATM. - * @returns Whether the GPT icon for summarization should appear - */ - canSummarize = (): boolean => { - const docs = SelectionManager.Docs(); - if (docs.length > 0) { - return docs.some(doc => doc.type === DocumentType.PDF || doc.type === DocumentType.WEB); - } - return false; - }; - - /** - * Returns whether the selected text can be edited. - * @returns Whether the GPT icon for summarization should appear - */ - canEdit = (): boolean => { - const docs = SelectionManager.Docs(); - if (docs.length > 0) { - return docs.some(doc => doc.type === 'rtf'); - } - return false; - }; render() { - const buttons = - this.Status === 'marquee' ? ( - <> - {this.highlighter} - } - color={StrCast(Doc.UserDoc().userColor)} - /> - {/* GPT Summarize icon only shows up when text is highlighted, not on marquee selection*/} - {MapAnchorMenu.Instance.StartCropDrag === unimplementedFunction && this.canSummarize() && ( - } - color={StrCast(Doc.UserDoc().userColor)} - /> - )} - - {MapAnchorMenu.Instance.OnAudio === unimplementedFunction ? null : ( - } - color={StrCast(Doc.UserDoc().userColor)} - /> - )} - {this.canEdit() && ( - } - color={StrCast(Doc.UserDoc().userColor)} - /> - )} - } - popup={} - color={StrCast(Doc.UserDoc().userColor)} - /> - {MapAnchorMenu.Instance.StartCropDrag === unimplementedFunction ? null : ( - } - color={StrCast(Doc.UserDoc().userColor)} - /> - )} - - ) : ( + const buttons =( <> - {this.Delete !== returnFalse && ( + {( } color={StrCast(Doc.UserDoc().userColor)} /> )} - {this.PinToPres !== returnFalse && ( + {( } color={StrCast(Doc.UserDoc().userColor)} /> )} - {this.ShowTargetTrail !== returnFalse && ( + {( } color={StrCast(Doc.UserDoc().userColor)} /> )} - {this.IsTargetToggler !== returnFalse && ( + {/* {this.IsTargetToggler !== returnFalse && ( { icon={} color={StrCast(Doc.UserDoc().userColor)} /> - )} + )} */} ); - return this.getElement(buttons); + return this.getElement(
+ {buttons} +
+ ); } } diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index be2defa9b..14ecc910e 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -5,6 +5,7 @@ import { Button, EditableText, IconButton, Type } from 'browndash-components'; import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { TbHeartMinus } from 'react-icons/tb'; import { Doc, DocListCast, Opt } from '../../../../fields/Doc'; import { Width } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; @@ -26,6 +27,7 @@ import { SidebarAnnos } from '../../SidebarAnnos'; import { DocumentView, OpenWhere } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; import { PinProps, PresBox } from '../trails'; +import { MapAnchorMenu } from './MapAnchorMenu'; import './MapBox.scss'; // amongus /** @@ -116,9 +118,8 @@ export class MapBox extends ViewBoxAnnotatableComponent = React.createRef(); - @observable _showSidebar = false; @computed get SidebarShown() { - return this._showSidebar || this.layoutDoc._layout_showSidebar ? true : false; + return this.layoutDoc._layout_showSidebar ? true : false; } static _canAnnotate = true; @@ -299,11 +300,11 @@ export class MapBox extends ViewBoxAnnotatableComponent 0) { - this._showSidebar = true; + this.layoutDoc._layout_showSidebar = true; this.layoutDoc._width = fullWidth + localDelta[0]; this.layoutDoc._layout_sidebarWidthPercent = ((100 * (this.sidebarWidth() + localDelta[0])) / (fullWidth + localDelta[0])).toString() + '%'; } else { - this._showSidebar = false; + this.layoutDoc._layout_showSidebar = false; this.layoutDoc._width = mapWidth; this.layoutDoc._layout_sidebarWidthPercent = '0%'; } @@ -505,13 +506,14 @@ export class MapBox extends ViewBoxAnnotatableComponent { - if (pinDoc) this.removePushpin(pinDoc, pin); - else this._bingMap.current.entities.remove(pin); - }; + // @action + // pushpinDblClicked = (pin: any, pinDoc?: Doc) => { + // if (pinDoc) this.removePushpin(pinDoc); + // else this._bingMap.current.entities.remove(pin); + // }; // The pin that is selected + @observable selectedPin:Doc | undefined; /* @@ -519,18 +521,37 @@ export class MapBox extends ViewBoxAnnotatableComponent { - // TODO: - // if (sidebarannos is not open) open sidebarannos - // creates button onclick removes the doc from annotations + if (this.selectedPin) { + const temp = this.selectedPin; + this._bingMap.current.entities.remove(this.map_docToPinMap.get(temp)); + const newpin = new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(temp.latitude,temp.longitude)); + this.MicrosoftMaps.Events.addHandler(newpin, 'click', (e: any) => this.pushpinClicked(temp as Doc)); + this._bingMap.current.entities.push(newpin); + this.map_docToPinMap.set(temp, newpin); + } + + this.selectedPin = pinDoc; - // pan to pushpin location - // this.dataDoc.latitude = pinDoc.latitude; - // this.dataDoc.longitude = pinDoc.longitude; - this.selectedPin = pinDoc + this._bingMap.current.entities.remove(this.map_docToPinMap.get(this.selectedPin)); + const newpin = new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(this.selectedPin.latitude,this.selectedPin.longitude), { + color: 'green', + }) + this.MicrosoftMaps.Events.addHandler(newpin, 'click', (e: any) => this.pushpinClicked(this.selectedPin as Doc)); + this._bingMap.current.entities.push(newpin); + this.map_docToPinMap.set(this.selectedPin, newpin); - /// this should SELECT, not center + MapAnchorMenu.Instance.Delete = this.deleteSelectedPin + MapAnchorMenu.Instance.Center = this.centerOnSelectedPin; + MapAnchorMenu.Instance.LinkNote = this.createNoteAnnotation; + + const point = this._bingMap.current.tryLocationToPixel(new this.MicrosoftMaps.Location(this.selectedPin.latitude,this.selectedPin.longitude)) + const x = point.x + this.props.PanelWidth() / 2; + const y = point.y + this.props.PanelHeight() / 2 +32 + const cpt = this.props.ScreenToLocalTransform().inverse().transformPoint(x, y); + MapAnchorMenu.Instance.jumpTo(cpt[0] - this.sidebarWidth()/this.panelWidth()*200, cpt[1], true); + document.addEventListener('pointerdown', this.tryHideMapAnchorMenu, true) + this.MicrosoftMaps.Events.addHandler(this._bingMap.current, 'click', this.mapOnClick); - this.createNoteAnnotation(); }; /** @@ -545,10 +566,16 @@ export class MapBox extends ViewBoxAnnotatableComponent { - if (this.placePinOn) { - this.createPushpin(e.location.latitude, e.location.longitude); - // this.addAllPins(); - // this.placePinOn = false; + if (this.selectedPin) { + const temp = this.selectedPin; + this._bingMap.current.entities.remove(this.map_docToPinMap.get(temp)); + const newpin = new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(temp.latitude,temp.longitude)); + this.MicrosoftMaps.Events.addHandler(newpin, 'click', (e: any) => this.pushpinClicked(temp as Doc)); + this._bingMap.current.entities.push(newpin); + this.map_docToPinMap.set(temp, newpin); + + this.selectedPin=undefined; + this.MicrosoftMaps.Events.removeEventListener(this._bingMap.current, 'click', this.mapOnClick); } }; @@ -585,26 +612,8 @@ export class MapBox extends ViewBoxAnnotatableComponent this.pushpinDblClicked(temp)); - if (temp != this.searched_pin || this.searched_pin == null) { - this._bingMap.current.entities.push(temp); - this.searched_pin = temp; - } + this.createPushpin(this.dataDoc.latitude, this.dataDoc.longitude) }; /** @@ -624,8 +633,8 @@ export class MapBox extends ViewBoxAnnotatableComponent(); /* * Input: pin doc * Adds MicrosoftMaps Pushpin to the map (render) @@ -658,7 +668,8 @@ export class MapBox extends ViewBoxAnnotatableComponent this.pushpinClicked(pin)); - this.MicrosoftMaps.Events.addHandler(pushPin, 'dblclick', (e: any) => this.pushpinDblClicked(pushPin, pin)); + // this.MicrosoftMaps.Events.addHandler(pushPin, 'dblclick', (e: any) => this.pushpinDblClicked(pushPin, pin)); + this.map_docToPinMap.set(pin,pushPin); }; @observable @@ -666,24 +677,72 @@ export class MapBox extends ViewBoxAnnotatableComponent { + removePushpin = (pinDoc: Doc) => { // this.allMapPushpins // this.allMapPushpins.map(pin => this.addPushpin(pin)); // this._bingMap.current.entities.clear(); - this._bingMap.current.entities.remove(pin); + this.removeDocument(pinDoc, this.annotationKey); // this.dataDoc[this.annotationKey] }; + /* + * Removes pushpin from map render + */ + deletePushpin = (pinDoc:Doc)=>{ + this._bingMap.current.entities.remove(this.map_docToPinMap.get(pinDoc)); + this.map_docToPinMap.delete(pinDoc); + this.selectedPin=undefined; + } + + @action + deleteSelectedPin = undoable(()=>{ + if (this.selectedPin){ + this.removePushpin(this.selectedPin) + + } + MapAnchorMenu.Instance.fadeOut(true); + document.removeEventListener('pointerdown', this.tryHideMapAnchorMenu, true) + }, "delete pin"); + + tryHideMapAnchorMenu = (e:PointerEvent) =>{ + let target = document.elementFromPoint(e.x, e.y); + + while (target != null) { + if (target === MapAnchorMenu.top.current) { + return; + } + target = target.parentElement; + } + e.stopPropagation(); + e.preventDefault(); + MapAnchorMenu.Instance.fadeOut(true); + document.removeEventListener('pointerdown', this.tryHideMapAnchorMenu, true) + + } + + // tryhidemenu = e => if( e.parent... == mapanchormenu.top.currrent) do nothing; else hide menu + + @action + centerOnSelectedPin = () =>{ + if (this.selectedPin){ + this.dataDoc.latitude = this.selectedPin.latitude; + this.dataDoc.longitude = this.selectedPin.longitude; + + + } + MapAnchorMenu.Instance.fadeOut(true); + document.removeEventListener('pointerdown', this.tryHideMapAnchorMenu) + } /** * View options for bing maps */ bingViewOptions = { - center: { latitude: this.dataDoc.latitude ?? defaultCenter.lat, longitude: this.dataDoc.longitude ?? defaultCenter.lng }, + // center: { latitude: this.dataDoc.latitude ?? defaultCenter.lat, longitude: this.dataDoc.longitude ?? defaultCenter.lng }, zoom: this.dataDoc.latitude ?? 10, mapTypeId: 'grayscale', }; @@ -734,10 +793,9 @@ export class MapBox extends ViewBoxAnnotatableComponent ({ lat: this.rootDoc.latitude, lng: this.rootDoc.longitude, zoom: this.rootDoc.mapZoom, mapType: this.rootDoc.mapType }), @@ -756,13 +814,13 @@ export class MapBox extends ViewBoxAnnotatableComponent { - console.log('DRAGGING TOGGLE'); + // console.log('DRAGGING TOGGLE'); document.addEventListener('drop', this.dropPin, true); document.addEventListener('pointermove', this.pinMove, true); e.stopPropagation(); }; pinMove = (e: PointerEvent) => { - console.log('MOVING'); + // console.log('MOVING'); e.stopPropagation(); }; dropPin = (e: DragEvent) => { diff --git a/src/client/views/nodes/MapBox/MapPushpinBox.tsx b/src/client/views/nodes/MapBox/MapPushpinBox.tsx index d28209ea1..66fe1ce53 100644 --- a/src/client/views/nodes/MapBox/MapPushpinBox.tsx +++ b/src/client/views/nodes/MapBox/MapPushpinBox.tsx @@ -19,7 +19,7 @@ export class MapPushpinBox extends ViewBoxBaseComponent() { this.mapBoxView.addPushpin(this.rootDoc); } componentWillUnmount() { - // this.mapBoxView.removePushpin(this.rootDoc); + this.mapBoxView.deletePushpin(this.rootDoc); } @computed get mapBoxView() { -- cgit v1.2.3-70-g09d2 From e6d135c656645873eeb477974a345d62b17bc9cd Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 26 Aug 2023 22:50:09 -0400 Subject: from last --- src/client/views/nodes/MapBox/MapPushpinBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/nodes/MapBox/MapPushpinBox.tsx') diff --git a/src/client/views/nodes/MapBox/MapPushpinBox.tsx b/src/client/views/nodes/MapBox/MapPushpinBox.tsx index 66fe1ce53..552bceace 100644 --- a/src/client/views/nodes/MapBox/MapPushpinBox.tsx +++ b/src/client/views/nodes/MapBox/MapPushpinBox.tsx @@ -30,6 +30,6 @@ export class MapPushpinBox extends ViewBoxBaseComponent() { } render() { - return
; + return
; } } -- cgit v1.2.3-70-g09d2