aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric <ericmabr@gmail.com>2023-08-22 16:31:00 -0400
committerEric <ericmabr@gmail.com>2023-08-22 16:31:00 -0400
commite724cf830b773d22bada7c319f5c2527b2ffeae7 (patch)
tree20b361f5bbc5c460c68df43fe8628a11cc4e8213
parent696b54d2d6321ebd194dbe1f5cf823320036f8fe (diff)
Everything working, except for offset of placing pins and mapanchormenu when sidebar is open
-rw-r--r--src/client/util/CurrentUserUtils.ts2
-rw-r--r--src/client/views/MainView.tsx2
-rw-r--r--src/client/views/nodes/MapBox/MapAnchorMenu.tsx355
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx162
-rw-r--r--src/client/views/nodes/MapBox/MapPushpinBox.tsx2
5 files changed, 168 insertions, 355 deletions
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<string>(["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 {
<ContextMenu />
<RadialMenu />
<AnchorMenu />
+ <MapAnchorMenu/>
<DashFieldViewMenu />
<MarqueeOptionsMenu />
<OverlayView />
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<AntimodeMenuProps> {
@@ -24,73 +24,22 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
private _disposer2: IReactionDisposer | undefined;
private _commentCont = React.createRef<HTMLButtonElement>();
- @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<Doc> = () => 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<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => Opt<Doc> = (color: string, isTargetToggler: boolean) => undefined;
public GetAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, 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<AntimodeMenuProps> {
() => this._opacity,
opacity => {
if (!opacity) {
- this.setGPTPopupVis(false);
- this.setGPTPopupText('');
}
},
{ fireImmediately: true }
@@ -122,259 +69,62 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
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<HTMLDivElement>();
+ // 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 (
- <Group>
- <IconButton
- icon={<FontAwesomeIcon icon="highlighter" style={{ transition: 'transform 0.1s', transform: 'rotate(-45deg)' }} />}
- tooltip={'Click to Highlight'}
- onClick={this.highlightClicked}
- colorPicker={this.highlightColor}
- color={StrCast(Doc.UserDoc().userColor)}
- />
- <ColorPicker selectedColor={this.highlightColor} setFinalColor={this.changeHighlightColor} setSelectedColor={this.changeHighlightColor} size={Size.XSMALL} />
- </Group>
- );
- }
-
- @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}
- <IconButton
- tooltip="Drag to Place Annotation" //
- onPointerDown={this.pointerDown}
- icon={<FontAwesomeIcon icon="comment-alt" />}
- 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() && (
- <IconButton
- tooltip="Summarize with AI" //
- onPointerDown={this.gptSummarize}
- icon={<FontAwesomeIcon icon="comment-dots" size="lg" />}
- color={StrCast(Doc.UserDoc().userColor)}
- />
- )}
- <GPTPopup
- key="gptpopup"
- visible={this.showGPTPopup}
- text={this.GPTpopupText}
- highlightRange={this.highlightRange}
- loading={this.loadingGPT}
- callSummaryApi={this.gptSummarize}
- callEditApi={this.gptEdit}
- replaceText={this.replaceText}
- mode={this.GPTMode}
- />
- {MapAnchorMenu.Instance.OnAudio === unimplementedFunction ? null : (
- <IconButton
- tooltip="Click to Record Annotation" //
- onPointerDown={this.audioDown}
- icon={<FontAwesomeIcon icon="microphone" />}
- color={StrCast(Doc.UserDoc().userColor)}
- />
- )}
- {this.canEdit() && (
- <IconButton
- tooltip="AI edit suggestions" //
- onPointerDown={this.gptEdit}
- icon={<FontAwesomeIcon icon="pencil-alt" />}
- color={StrCast(Doc.UserDoc().userColor)}
- />
- )}
- <Popup
- tooltip="Find document to link to selected text" //
- type={Type.PRIM}
- icon={<FontAwesomeIcon icon={'search'} />}
- popup={<LinkPopup key="popup" linkCreateAnchor={this.onMakeAnchor} />}
- color={StrCast(Doc.UserDoc().userColor)}
- />
- {MapAnchorMenu.Instance.StartCropDrag === unimplementedFunction ? null : (
- <IconButton
- tooltip="Click/Drag to create cropped image" //
- onPointerDown={this.cropDown}
- icon={<FontAwesomeIcon icon="image" />}
- color={StrCast(Doc.UserDoc().userColor)}
- />
- )}
- </>
- ) : (
+ const buttons =(
<>
- {this.Delete !== returnFalse && (
+ {(
<IconButton
- tooltip="Remove Link Anchor" //
+ tooltip="Delete Pin" //
onPointerDown={this.Delete}
icon={<FontAwesomeIcon icon="trash-alt" />}
color={StrCast(Doc.UserDoc().userColor)}
/>
)}
- {this.PinToPres !== returnFalse && (
+ {(
<IconButton
- tooltip="Pin to Presentation" //
- onPointerDown={this.PinToPres}
+ tooltip="Link Note to Pin" //
+ onPointerDown={this.LinkNote}
icon={<FontAwesomeIcon icon="map-pin" />}
color={StrCast(Doc.UserDoc().userColor)}
/>
)}
- {this.ShowTargetTrail !== returnFalse && (
+ {(
<IconButton
- tooltip="Show Linked Trail" //
- onPointerDown={this.ShowTargetTrail}
+ tooltip="Center on pin" //
+ onPointerDown={this.Center}
icon={<FontAwesomeIcon icon="taxi" />}
color={StrCast(Doc.UserDoc().userColor)}
/>
)}
- {this.IsTargetToggler !== returnFalse && (
+ {/* {this.IsTargetToggler !== returnFalse && (
<Toggle
tooltip={'Make target visibility toggle on click'}
type={Type.PRIM}
@@ -384,10 +134,13 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
icon={<FontAwesomeIcon icon="thumbtack" />}
color={StrCast(Doc.UserDoc().userColor)}
/>
- )}
+ )} */}
</>
);
- return this.getElement(buttons);
+ return this.getElement(<div ref={MapAnchorMenu.top} style={{width:"100%", display:"flex"}}>
+ {buttons}
+ </div>
+ );
}
}
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<ViewBoxAnnotatableProps
@observable private toggleAddMarker = false;
private _mainCont: React.RefObject<HTMLDivElement> = 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<ViewBoxAnnotatableProps
const fullWidth = this.layoutDoc[Width]();
const mapWidth = fullWidth - this.sidebarWidth();
if (this.sidebarWidth() + localDelta[0] > 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<ViewBoxAnnotatableProps
/*
* Pushpin dblclick
*/
- @action
- pushpinDblClicked = (pin: any, pinDoc?: Doc) => {
- 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<ViewBoxAnnotatableProps
*/
@action
pushpinClicked = (pinDoc: Doc) => {
- // 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<ViewBoxAnnotatableProps
*/
@action
mapOnClick = (e: { location: { latitude: any; longitude: any } }) => {
- 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<ViewBoxAnnotatableProps
this.dataDoc.latitude = location.latitude;
this.dataDoc.longitude = location.longitude;
this.dataDoc.mapZoom = this._bingMap.current.getZoom();
- // this.dataDoc.mapType = this._bingMap.current.getMapTypeId();
- // this.bingSearchBarContents=location.name;
-
- // Centers on the searched location
- // this._bingMap.current.panTo(new this.MicrosoftMaps.Location(this.dataDoc.latitude, this.dataDoc.longitude));
-
- // this._bingMap.current.setView({
- // center: new this.MicrosoftMaps.Location(this.dataDoc.latitude, this.dataDoc.longitude),
- // });
-
// 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), {
- color: 'blue',
- });
-
- this.MicrosoftMaps.Events.addHandler(temp, 'dblclick', (e: any) => 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<ViewBoxAnnotatableProps
/// this should use SELECTED pushpin for lat/long if there is a selection, otherwise CENTER
const anchor = Docs.Create.MapanchorDocument({
title: 'MapAnchor:' + this.rootDoc.title,
- config_latitude: NumCast(this.selectedPin ? this.selectedPin.latitude : this.dataDoc.latitude),
- config_longitude: NumCast(this.selectedPin ? this.selectedPin.longitude : this.dataDoc.longitude),
+ config_latitude: NumCast(this.selectedPin?.latitude ?? this.dataDoc.latitude),
+ config_longitude: NumCast(this.selectedPin?.longitude ?? this.dataDoc.longitude),
config_mapZoom: NumCast(this.dataDoc.mapZoom),
config_mapType: StrCast(this.dataDoc.mapType),
// preslocationToLookAt:this.dataDoc.locationToLookAt,
@@ -642,6 +651,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
return this.rootDoc;
};
+ map_docToPinMap = new Map<Doc, any>();
/*
* Input: pin doc
* Adds MicrosoftMaps Pushpin to the map (render)
@@ -658,7 +668,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this._bingMap.current.entities.push(pushPin);
this.MicrosoftMaps.Events.addHandler(pushPin, 'click', (e: any) => 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<ViewBoxAnnotatableProps
/*
* Input: pin doc
- * Removes MicrosoftMaps Pushpin to the map (render)
+ * Removes pin from annotations
*/
@action
- removePushpin = (pinDoc: Doc, pin: any) => {
+ 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<ViewBoxAnnotatableProps
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.updateLayout();
// this.updateMapType();
this._disposer.location = reaction(
() => ({ 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<ViewBoxAnnotatableProps
// Keeps track of when dragging a pin onto map
draggingPin = false;
dragToggle = (e: React.PointerEvent) => {
- 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<FieldViewProps>() {
this.mapBoxView.addPushpin(this.rootDoc);
}
componentWillUnmount() {
- // this.mapBoxView.removePushpin(this.rootDoc);
+ this.mapBoxView.deletePushpin(this.rootDoc);
}
@computed get mapBoxView() {