aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx207
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx4
-rw-r--r--src/server/DashSession/Session/agents/process_message_router.ts2
3 files changed, 162 insertions, 51 deletions
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 0cf3ae326..4c0c4c0c7 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -2,11 +2,11 @@ import { Autocomplete, GoogleMap, GoogleMapProps, InfoWindow, Marker } from '@re
import { action, computed, IReactionDisposer, observable, ObservableMap } from 'mobx';
import { observer } from "mobx-react";
import * as React from "react";
-import { DataSym, Doc, DocListCast, FieldsSym, WidthSym } from '../../../../fields/Doc';
+import { DataSym, Doc, DocListCast, FieldsSym, Opt, WidthSym } from '../../../../fields/Doc';
import { documentSchema } from '../../../../fields/documentSchemas';
import { makeInterface } from '../../../../fields/Schema';
import { NumCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, setupMoveUpEvents } from '../../../../Utils';
+import { emptyFunction, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils';
import { Docs } from '../../../documents/Documents';
import { DragManager } from '../../../util/DragManager';
import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent';
@@ -21,6 +21,13 @@ import { identity } from 'lodash';
import { Id } from '../../../../fields/FieldSymbols';
import { Colors } from '../../global/globalEnums';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { TraceMobx } from '../../../../fields/util';
+import { SnappingManager } from '../../../util/SnappingManager';
+import { InkTool } from '../../../../fields/InkField';
+import { CurrentUserUtils } from '../../../util/CurrentUserUtils';
+import { CollectionFreeFormView } from '../../collections/collectionFreeForm';
+import { MarqueeAnnotator } from '../../MarqueeAnnotator';
+import { Annotation } from '../../pdf/Annotation';
type MapDocument = makeInterface<[typeof documentSchema]>;
const MapDocument = makeInterface(documentSchema);
@@ -72,25 +79,34 @@ const options = {
export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps & Partial<GoogleMapProps>, MapDocument>(MapDocument) {
private _dropDisposer?: DragManager.DragDropDisposer;
private _disposers: { [name: string]: IReactionDisposer } = {};
+ private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
+ @observable private _overlayAnnoInfo: Opt<Doc>;
+ showInfo = action((anno: Opt<Doc>) => this._overlayAnnoInfo = anno);
public static LayoutString(fieldKey: string) { return FieldView.LayoutString(MapBox, fieldKey); }
+ public get SidebarKey() { return this.fieldKey + "-sidebar"; }
+ private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean) => void);
+ @computed get inlineTextAnnotations() { return this.allMapMarkers.filter(a => a.textInlineAnnotations); }
@observable private _map: google.maps.Map = null as unknown as google.maps.Map;
- @observable private selectedPlace: MapMarker | undefined;
+ @observable private selectedPlace: MapMarker | Doc | undefined;
@observable private markerMap: { [id: string]: google.maps.Marker } = {};
@observable private center = navigator.geolocation ? navigator.geolocation.getCurrentPosition : defaultCenter;
@observable private zoom = 2.5;
@observable private infoWindowOpen = false;
+ @observable private _marqueeing: number[] | undefined;
+ @observable private _isAnnotating = false;
@observable private bounds = new window.google.maps.LatLngBounds();
@observable private inputRef = React.createRef<HTMLInputElement>();
@observable private searchMarkers: google.maps.Marker[] = [];
@observable private searchBox = new window.google.maps.places.Autocomplete(this.inputRef.current!, options);
@observable private _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
@computed get allSidebarDocs() { return DocListCast(this.dataDoc[this.SidebarKey]); };
- @computed get allMapMarkers() { return DocListCast(this.dataDoc[this.annotationKey]); };
- @observable private allMarkers: Doc[] = [];
+ @computed get allMapMarkers() { return DocListCast(this.dataDoc[this.annotationKey]); }; // method to add MapMarker to allMapMarkers
//TODO: change all markers to a filter function to change
@observable private toggleAddMarker = false;
+ private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
+
@observable _showSidebar = false;
@computed get SidebarShown() { return this._showSidebar || this.layoutDoc._showSidebar ? true : false; }
@@ -112,7 +128,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
// iterate allMarkers to size, center, and zoom map to contain all markers
private fitBounds = (map: google.maps.Map) => {
console.log('map bound is:' + this.bounds);
- this.allMarkers.map(place => {
+ this.allMapMarkers.map(place => {
this.bounds.extend({ lat: NumCast(place.lat), lng: NumCast(place.lng) });
return place._markerId;
});
@@ -185,29 +201,28 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
});
map.panTo(position);
const mapMarker = Docs.Create.MapMarkerDocument(NumCast(position.lat()), NumCast(position.lng()), [], {});
- this.allMarkers.push(mapMarker);
+ this.addDocument(mapMarker, this.annotationKey);
+ // Doc.AddDocToList(this.dataDoc, this.annotationKey, mapMarker);
}
/**
* A function that examines allMapMarkers docs in the map node and form MapMarkers
*/
- private fillMarkers = () => {
- this.allMapMarkers?.forEach(doc => {
- console.log(doc);
- // search for if the map marker exists, else create marker
- if (doc.lat !== undefined && doc.lng !== undefined) {
- console.log("image found! loading into marker document...")
- const marker = Docs.Create.MapMarkerDocument(NumCast(doc.lat), NumCast(doc.lng), [doc], {})
- this.allMarkers.push(marker)
- }
- })
- }
-
- // TODO: things to ask & think about when designing
- // 1. All markers are stored in allMarkers[], when adding a new marker (from a button, ideally not using drawManager),
- // the new marker will be stored in allMarkers[]
- // currently markerloadhandler only gets called when the map is reloaded, but we want it to be update on the GUI in real time
- // TODO ** core issue --> real time updates **
+ // private fillMarkers = () => {
+ // // console.log("allSidebarDocs:");
+ // // console.log(this.allSidebarDocs);
+ // this.allSidebarDocs?.forEach(doc => {
+ // console.log(doc);
+ // // search for if the map marker exists, else create marker
+ // if (doc.lat !== undefined && doc.lng !== undefined) {
+ // console.log("image found! loading into marker document...")
+ // const marker = Docs.Create.MapMarkerDocument(NumCast(doc.lat), NumCast(doc.lng), [doc], {})
+ // Doc.AddDocToList(this.dataDoc, this.annotationKey, marker) // add marker to annotation key
+ // }
+ // });
+ // // console.log("allMarkers:")
+ // // console.log(this.allMarkers);
+ // }
/**
@@ -235,20 +250,19 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
);
} else {
alert("Your geolocation is not supported by browser.")
- }
- this.fitBounds(map);
- console.log("content in the allMapsMarker array:");
- console.log(this.allMapMarkers);
- console.log("content in the sidebarDocs array:");
+ };
+ console.log("all sidebar docs during map loading is:")
console.log(this.allSidebarDocs);
- this.fillMarkers();
+ this.fitBounds(map);
+ // this.fillMarkers();
+
// listener to addmarker event
this._map.addListener('click', (e) => {
console.log("add marker map status:" + this.toggleAddMarker);
if (this.toggleAddMarker == true) {
this.placeMarker(e.latLng, map)
- console.log(this.allMarkers)
+ console.log(this.allMapMarkers)
}
})
// this._map.addListener(drawingManager, 'markercomplete', this.addMarker)
@@ -281,10 +295,11 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
@action
- private markerClickHandler = (e: MouseEvent, place: any) => {
+ private markerClickHandler = (e: MouseEvent, place: Doc) => {
// set which place was clicked
this.selectedPlace = place;
+ console.log("you have selected this location:");
console.log(this.selectedPlace);
// used so clicking a second marker works
@@ -303,6 +318,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
* @returns
*/
sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
+ console.log("print all sidebar Docs");
+ console.log(this.allSidebarDocs);
if (!this.layoutDoc._showSidebar) this.toggleSidebar();
const docs = doc instanceof Doc ? [doc] : doc
docs.forEach(doc => {
@@ -311,11 +328,14 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this.addDocument(marker, this.annotationKey)
}
}) //add to annotation list
+ console.log("sidebaraddDocument");
+ console.log(doc);
+
return this.addDocument(doc, sidebarKey); // add to sidebar list
}
/**
- * What does this do exactly? How to operate on sidebar?
+ * Toggle sidebar onclick the tiny comment button on the top right corner
* @param e
*/
sidebarBtnDown = (e: React.PointerEvent) => {
@@ -397,16 +417,26 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this.selectedPlace = undefined;
}
- public get SidebarKey() { return this.fieldKey + "-sidebar"; }
-
@computed get sidebarHandle() {
+ TraceMobx();
const annotated = DocListCast(this.dataDoc[this.SidebarKey]).filter(d => d?.author).length;
- //&& !this.isContentActive()
- return (!annotated) ? (null) : <div className="mapBox-sidebar-handle" onPointerDown={this.sidebarDown}
- style={{
- left: `max(0px, calc(100% - ${this.sidebarWidthPercent} ${this.sidebarWidth() ? "- 5px" : "- 10px"}))`,
- background: this.props.styleProvider?.(this.rootDoc, this.props as any, StyleProp.WidgetColor + (annotated ? ":annotated" : ""))
- }} />;
+ const color = !annotated ? Colors.WHITE : Colors.BLACK;
+ const backgroundColor = !annotated ? this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK : this.props.styleProvider?.(this.rootDoc, this.props as any, StyleProp.WidgetColor + (annotated ? ":annotated" : ""));
+ return (!annotated) ? (null) :
+ <div className="formattedTextBox-sidebar-handle" onPointerDown={this.sidebarDown}
+ style={{
+ left: `max(0px, calc(100% - ${this.sidebarWidthPercent} - 17px))`,
+ backgroundColor: backgroundColor,
+ color: color,
+ opacity: annotated ? 1 : undefined
+ }} >
+ <FontAwesomeIcon icon={"comment-alt"} />
+ </div>;
+ // return (!annotated) ? (null) : <div className="mapBox-sidebar-handle" onPointerDown={this.sidebarDown}
+ // style={{
+ // left: `max(0px, calc(100% - ${this.sidebarWidthPercent} ${this.sidebarWidth() ? "- 5px" : "- 10px"}))`,
+ // background: this.props.styleProvider?.(this.rootDoc, this.props as any, StyleProp.WidgetColor + (annotated ? ":annotated" : ""))
+ // }} />;
}
@action
@@ -415,6 +445,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this.layoutDoc._showSidebar = ((this.layoutDoc._sidebarWidthPercent = StrCast(this.layoutDoc._sidebarWidthPercent, "0%") === "0%" ? "50%" : "0%")) !== "0%";
this.layoutDoc._width = this.layoutDoc._showSidebar ? NumCast(this.layoutDoc._width) * 2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth);
}
+
sidebarDown = (e: React.PointerEvent) => {
setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, () => setTimeout(this.toggleSidebar), false);
}
@@ -426,7 +457,29 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
return false;
}
- // TODO what's the difference between savedAnnotations & allMapMarkers?
+ setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean) => void) => this._setPreviewCursor = func;
+
+ @action
+ onMarqueeDown = (e: React.PointerEvent) => {
+ if (!e.altKey && e.button === 0 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
+ setupMoveUpEvents(this, e, action(e => {
+ MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
+ this._marqueeing = [e.clientX, e.clientY];
+ return true;
+ }), returnFalse, () => MarqueeAnnotator.clearAnnotations(this._savedAnnotations), false);
+ }
+ }
+ @action finishMarquee = (x?: number, y?: number) => {
+ this._marqueeing = undefined;
+ this._isAnnotating = false;
+ x !== undefined && y !== undefined && this._setPreviewCursor?.(x, y, false, false);
+ }
+
+ addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => {
+ return this.addDocument(doc, annotationKey);
+ }
+
+
getAnchor = () => {
const anchor =
AnchorMenu.Instance?.GetAnchor(this._savedAnnotations) ??
@@ -440,12 +493,9 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
return anchor;
}
- private saveMarkerInfo = () => {
-
- }
// create marker prop --> func that
private renderMarkers = () => {
- return this.allMarkers.map(place => (
+ return this.allMapMarkers.map(place => (
<Marker
key={place[Id]}
position={{ lat: NumCast(place.lat), lng: NumCast(place.lng) }}
@@ -458,7 +508,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
private renderInfoWindow = () => {
return this.infoWindowOpen && this.selectedPlace && (
<InfoWindow
- anchor={this.markerMap[this.selectedPlace._markerId!]}
+ // anchor={this.markerMap[this.selectedPlace.Id!]}
onCloseClick={this.handleInfoWindowClose}
>
<div style={{ backgroundColor: 'white', opacity: 0.75, padding: 12 }}>
@@ -485,7 +535,48 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
)
}
+ panelWidth = () => this.props.PanelWidth() / (this.props.scaling?.() || 1) - this.sidebarWidth(); // (this.Document.scrollHeight || Doc.NativeHeight(this.Document) || 0);
+ panelHeight = () => this.props.PanelHeight() / (this.props.scaling?.() || 1); // () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document);
+ scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop));
+ transparentFilter = () => [...this.props.docFilters(), Utils.IsTransparentFilter()];
+ opaqueFilter = () => [...this.props.docFilters(), Utils.IsOpaqueFilter()];
+
+ anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick;
+
+ @computed get annotationLayer() {
+ TraceMobx();
+ return <div className="webBox-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) || undefined }} ref={this._annotationLayer}>
+ {this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno =>
+ <Annotation {...this.props} fieldKey={this.annotationKey} showInfo={this.showInfo} dataDoc={this.dataDoc} anno={anno} key={`${anno[Id]}-annotation`} />)
+ }
+ </div>;
+
+ }
+
render() {
+ const renderAnnotations = (docFilters?: () => string[]) =>
+ <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
+ renderDepth={this.props.renderDepth + 1}
+ isAnnotationOverlay={true}
+ fieldKey={this.annotationKey}
+ CollectionView={undefined}
+ setPreviewCursor={this.setPreviewCursor}
+ PanelWidth={this.panelWidth}
+ PanelHeight={this.panelHeight}
+ ScreenToLocalTransform={this.scrollXf}
+ scaling={returnOne}
+ dropAction={"alias"}
+ docFilters={docFilters || this.props.docFilters}
+ dontRenderDocuments={docFilters ? false : true}
+ select={emptyFunction}
+ ContentScaling={returnOne}
+ bringToFront={emptyFunction}
+ whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
+ removeDocument={this.removeDocument}
+ moveDocument={this.moveDocument}
+ addDocument={this.sidebarAddDocument}
+ childPointerEvents={true}
+ pointerEvents={CurrentUserUtils.SelectedTool !== InkTool.None || this._isAnnotating || SnappingManager.GetIsDragging() ? "all" : "none"} />;
return <div className="mapBox" ref={this._ref}
// style={{ pointerEvents: this.isContentActive() ? undefined : "none" }}
>
@@ -497,10 +588,16 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
onWheel={e => e.stopPropagation()}
onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()}
style={{ width: `calc(100% - ${this.sidebarWidthPercent})` }}>
+
+ <div style={{ mixBlendMode: "multiply" }}>
+ {renderAnnotations(this.transparentFilter)}
+ </div>
+ {renderAnnotations(this.opaqueFilter)}
+ {SnappingManager.GetIsDragging() ? (null) : renderAnnotations()}
+ {this.annotationLayer}
<GoogleMap
mapContainerStyle={mapContainerStyle}
zoom={this.zoom}
- // center={this.center}
onLoad={map => this.loadHandler(map)}
options={mapOptions}
>
@@ -513,13 +610,24 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
{this.renderMarkers()}
{this.renderInfoWindow()}
</GoogleMap>
+ {!this._marqueeing || !this._mainCont.current || !this._annotationLayer.current ? (null) :
+ <MarqueeAnnotator rootDoc={this.rootDoc}
+ anchorMenuClick={this.anchorMenuClick}
+ scrollTop={0}
+ down={this._marqueeing} scaling={returnOne}
+ addDocument={this.addDocumentWrapper}
+ docView={this.props.docViewPath().lastElement()}
+ finishMarquee={this.finishMarquee}
+ savedAnnotations={this._savedAnnotations}
+ annotationLayer={this._annotationLayer.current}
+ mainCont={this._mainCont.current} />}
</div>
{/* {/* </LoadScript > */}
<div className="mapBox-sidebar"
style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
<SidebarAnnos ref={this._sidebarRef}
{...this.props}
- fieldKey={this.annotationKey}
+ fieldKey={this.fieldKey}
rootDoc={this.rootDoc}
layoutDoc={this.layoutDoc}
dataDoc={this.dataDoc}
@@ -530,7 +638,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
sidebarAddDocument={this.sidebarAddDocument}
moveDocument={this.moveDocument}
removeDocument={this.removeDocument}
- //isContentActive={this.isContentActive}
/>
</div>
<div className="mapBox-overlayButton-sidebar" key="sidebar" title="Toggle Sidebar"
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 63d2c1007..0d38bd5b8 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -120,6 +120,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
public ProseRef?: HTMLDivElement;
public get EditorView() { return this._editorView; }
public get SidebarKey() { return this.fieldKey + "-sidebar"; }
+ @computed get allSidebarDocs() { return DocListCast(this.dataDoc[this.SidebarKey]); };
@computed get sidebarWidthPercent() { return this._showSidebar ? "20%" : StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); }
@computed get sidebarColor() { return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "#e4e4e4")); }
@@ -1488,6 +1489,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
sidebarContentScaling = () => (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1);
sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
if (!this.layoutDoc._showSidebar) this.toggleSidebar();
+ // console.log("printting allSideBarDocs");
+ // console.log(this.allSidebarDocs);
return this.addDocument(doc, sidebarKey);
}
sidebarMoveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.moveDocument(doc, targetCollection, addDocument, this.SidebarKey);
@@ -1506,6 +1509,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
const annotated = DocListCast(this.dataDoc[this.SidebarKey]).filter(d => d?.author).length;
const color = !annotated ? Colors.WHITE : Colors.BLACK;
const backgroundColor = !annotated ? this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK : this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.WidgetColor + (annotated ? ":annotated" : ""));
+
return (!annotated && (!this.props.isContentActive() || SnappingManager.GetIsDragging())) ? (null) :
<div className="formattedTextBox-sidebar-handle" onPointerDown={this.sidebarDown}
style={{
diff --git a/src/server/DashSession/Session/agents/process_message_router.ts b/src/server/DashSession/Session/agents/process_message_router.ts
index 6cc8aa941..0745ea455 100644
--- a/src/server/DashSession/Session/agents/process_message_router.ts
+++ b/src/server/DashSession/Session/agents/process_message_router.ts
@@ -33,7 +33,7 @@ export default abstract class IPCMessageReceiver {
}
}
- /**
+ /**
* Unregister all listeners at this message.
*/
public clearMessageListeners = (...names: string[]) => names.map(name => delete this.handlers[name]);