From aa67222bc1a80ae11d1a29b32d5cb54199b38011 Mon Sep 17 00:00:00 2001 From: Aubrey-Li <63608597+Aubrey-Li@users.noreply.github.com> Date: Sat, 24 Jul 2021 11:15:04 -0700 Subject: backend issues with creating map node --- src/server/ApiManagers/DownloadManager.ts | 2 +- src/server/ApiManagers/SearchManager.ts | 1 + src/server/GarbageCollector.ts | 2 +- src/server/remapUrl.ts | 3 ++- src/server/updateProtos.ts | 2 +- src/server/websocket.ts | 1 + 6 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src/server') diff --git a/src/server/ApiManagers/DownloadManager.ts b/src/server/ApiManagers/DownloadManager.ts index 0d4472fdc..2175b6db6 100644 --- a/src/server/ApiManagers/DownloadManager.ts +++ b/src/server/ApiManagers/DownloadManager.ts @@ -112,7 +112,7 @@ async function getDocs(id: string) { const pathname = new URL(urlString).pathname; files.add(pathname); } - } else if (["audio", "image", "video", "pdf", "web"].includes(field.__type)) { + } else if (["audio", "image", "video", "pdf", "web", "map"].includes(field.__type)) { const url = new URL(field.url); const pathname = url.pathname; files.add(pathname); diff --git a/src/server/ApiManagers/SearchManager.ts b/src/server/ApiManagers/SearchManager.ts index 775e90520..a74e13a62 100644 --- a/src/server/ApiManagers/SearchManager.ts +++ b/src/server/ApiManagers/SearchManager.ts @@ -185,6 +185,7 @@ export namespace SolrManager { "pdf": ["_t", "url"], "audio": ["_t", "url"], "web": ["_t", "url"], + "map": ["_t", "url"], "date": ["_d", value => new Date(value.date).toISOString()], "proxy": ["_i", "fieldId"], "prefetch_proxy": ["_i", "fieldId"], diff --git a/src/server/GarbageCollector.ts b/src/server/GarbageCollector.ts index 7c441e3c0..c60880882 100644 --- a/src/server/GarbageCollector.ts +++ b/src/server/GarbageCollector.ts @@ -45,7 +45,7 @@ function addDoc(doc: any, ids: string[], files: { [name: string]: string[] }) { } exts.push(ext); } - } else if (["audio", "image", "video", "pdf", "web"].includes(field.__type)) { + } else if (["audio", "image", "video", "pdf", "web", "map"].includes(field.__type)) { const url = new URL(field.url); const pathname = url.pathname; const ext = path.extname(pathname); diff --git a/src/server/remapUrl.ts b/src/server/remapUrl.ts index 7178add93..e9f9da25a 100644 --- a/src/server/remapUrl.ts +++ b/src/server/remapUrl.ts @@ -8,7 +8,8 @@ const suffixMap: { [type: string]: true } = { "pdf": true, "audio": true, "web": true, - "image": true + "image": true, + "map": true, }; async function update() { diff --git a/src/server/updateProtos.ts b/src/server/updateProtos.ts index e9860bd61..c5552f6bf 100644 --- a/src/server/updateProtos.ts +++ b/src/server/updateProtos.ts @@ -1,7 +1,7 @@ import { Database } from "./database"; const protos = - ["text", "image", "web", "collection", "kvp", "video", "audio", "pdf", "icon", "import", "linkdoc"]; + ["text", "image", "web", "collection", "kvp", "video", "audio", "pdf", "icon", "import", "linkdoc", "map"]; (async function () { await Promise.all( diff --git a/src/server/websocket.ts b/src/server/websocket.ts index 4ae97913f..115baa0be 100644 --- a/src/server/websocket.ts +++ b/src/server/websocket.ts @@ -229,6 +229,7 @@ export namespace WebSocket { "pdf": ["_t", "url"], "audio": ["_t", "url"], "web": ["_t", "url"], + "map": ["_t", "url"], "script": ["_t", value => value.script.originalScript], "RichTextField": ["_t", value => value.Text], "date": ["_d", value => new Date(value.date).toISOString()], -- cgit v1.2.3-70-g09d2 From ff9c17fd3e4a32b63a365c7706656dc91095b082 Mon Sep 17 00:00:00 2001 From: Aubrey Li Date: Wed, 15 Sep 2021 20:54:16 -0400 Subject: merge conflicts and toggle sidebar --- src/client/views/nodes/MapBox/MapBox.scss | 22 ++++++++++++++++++++++ src/client/views/nodes/MapBox/MapBox.tsx | 26 +++++++++++++++++++++++--- src/server/public/files | 0 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 src/server/public/files (limited to 'src/server') diff --git a/src/client/views/nodes/MapBox/MapBox.scss b/src/client/views/nodes/MapBox/MapBox.scss index 4fae8d8ff..f275bed54 100644 --- a/src/client/views/nodes/MapBox/MapBox.scss +++ b/src/client/views/nodes/MapBox/MapBox.scss @@ -1,3 +1,4 @@ +@import "../../global/globalCssVariables.scss"; .mapBox { width: 100%; height: 100%; @@ -7,6 +8,27 @@ position: unset !important; // when the sidebar filter flys out, this prevents the map from extending outside the document box } + .mapBox-overlayButton-sidebar { + background: #121721; + height: 25px; + width: 25px; + right: 5px; + display: flex; + position: absolute; + align-items: center; + justify-content: center; + border-radius: 3px; + pointer-events: all; + z-index: 1; // so it appears on top of the document's title, if shown + + box-shadow: $standard-box-shadow; + transition: 0.2s; + + &:hover{ + filter: brightness(0.85); + } + } + .mapBox-wrapper { width: 100%; .searchbox { diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 0314aa419..1323048d9 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -19,6 +19,8 @@ import { MapMarker } from './MapMarker'; import { DocumentType } from '../../../documents/DocumentTypes'; import { identity } from 'lodash'; import { Id } from '../../../../fields/FieldSymbols'; +import { Colors } from '../../global/globalEnums'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; type MapDocument = makeInterface<[typeof documentSchema]>; const MapDocument = makeInterface(documentSchema); @@ -135,6 +137,12 @@ export class MapBox extends ViewBoxAnnotatableComponent real time updates ** + /** * store a reference to google map instance @@ -298,7 +306,8 @@ export class MapBox extends ViewBoxAnnotatableComponent d?.author).length; - return (!annotated && !this.isContentActive()) ? (null) :
+ // style={{ pointerEvents: this.isContentActive() ? undefined : "none" }} + > {/* // {/*
+
+ +
{this.sidebarHandle} ; } diff --git a/src/server/public/files b/src/server/public/files new file mode 100644 index 000000000..e69de29bb -- cgit v1.2.3-70-g09d2 From ccbe5e7dce400f6c2302436220de02a99032330f Mon Sep 17 00:00:00 2001 From: Aubrey Li Date: Wed, 15 Sep 2021 21:07:14 -0400 Subject: delete public/file --- src/server/public/files | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/server/public/files (limited to 'src/server') diff --git a/src/server/public/files b/src/server/public/files deleted file mode 100644 index e69de29bb..000000000 -- cgit v1.2.3-70-g09d2 From 3c1b393732ef9dc704a2f40b103c37b3f8370ba7 Mon Sep 17 00:00:00 2001 From: Aubrey Li Date: Tue, 26 Oct 2021 17:16:10 -0400 Subject: update Mapbox image rendering --- src/client/views/nodes/MapBox/MapBox.tsx | 207 ++++++++++++++++----- .../views/nodes/formattedText/FormattedTextBox.tsx | 4 + .../Session/agents/process_message_router.ts | 2 +- 3 files changed, 162 insertions(+), 51 deletions(-) (limited to 'src/server') 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, MapDocument>(MapDocument) { private _dropDisposer?: DragManager.DragDropDisposer; private _disposers: { [name: string]: IReactionDisposer } = {}; + private _annotationLayer: React.RefObject = React.createRef(); + @observable private _overlayAnnoInfo: Opt; + showInfo = action((anno: Opt) => 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(); @observable private searchMarkers: google.maps.Marker[] = []; @observable private searchBox = new window.google.maps.places.Autocomplete(this.inputRef.current!, options); @observable private _savedAnnotations = new ObservableMap(); @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 = 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 { 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 { - 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 { 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 { + 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 { + 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 { @@ -397,16 +417,26 @@ export class MapBox extends ViewBoxAnnotatableComponent d?.author).length; - //&& !this.isContentActive() - return (!annotated) ? (null) :
; + 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) : +
+ +
; + // return (!annotated) ? (null) :
; } @action @@ -415,6 +445,7 @@ export class MapBox extends ViewBoxAnnotatableComponent { setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, () => setTimeout(this.toggleSidebar), false); } @@ -426,7 +457,29 @@ export class MapBox extends ViewBoxAnnotatableComponent 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 { - - } // create marker prop --> func that private renderMarkers = () => { - return this.allMarkers.map(place => ( + return this.allMapMarkers.map(place => ( { return this.infoWindowOpen && this.selectedPlace && (
@@ -485,7 +535,48 @@ export class MapBox extends ViewBoxAnnotatableComponent 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
+ {this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno => + ) + } +
; + + } + render() { + const renderAnnotations = (docFilters?: () => string[]) => + ; return
@@ -497,10 +588,16 @@ export class MapBox extends ViewBoxAnnotatableComponent e.stopPropagation()} onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()} style={{ width: `calc(100% - ${this.sidebarWidthPercent})` }}> + +
+ {renderAnnotations(this.transparentFilter)} +
+ {renderAnnotations(this.opaqueFilter)} + {SnappingManager.GetIsDragging() ? (null) : renderAnnotations()} + {this.annotationLayer} this.loadHandler(map)} options={mapOptions} > @@ -513,13 +610,24 @@ export class MapBox extends ViewBoxAnnotatableComponent + {!this._marqueeing || !this._mainCont.current || !this._annotationLayer.current ? (null) : + }
{/* {/* */}
(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) :
names.map(name => delete this.handlers[name]); -- cgit v1.2.3-70-g09d2