From d5c261f306a45fda46e948b9db001874a2d9a0ae Mon Sep 17 00:00:00 2001 From: Aubrey-Li <63608597+Aubrey-Li@users.noreply.github.com> Date: Sat, 17 Jul 2021 12:58:57 -0700 Subject: add MapBox --- src/client/views/nodes/MapBox/MapBox.scss | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/client/views/nodes/MapBox/MapBox.scss (limited to 'src/client/views/nodes/MapBox/MapBox.scss') diff --git a/src/client/views/nodes/MapBox/MapBox.scss b/src/client/views/nodes/MapBox/MapBox.scss new file mode 100644 index 000000000..863907aaf --- /dev/null +++ b/src/client/views/nodes/MapBox/MapBox.scss @@ -0,0 +1,32 @@ +.MapBox { + width: 100%; + height: 100%; + overflow: hidden; + + .MapBox-contents { + width: 100%; + height: 100%; + overflow: hidden; + > div { + position: unset !important; // when the sidebar filter flys out, this prevents the map from extending outside the document box + } + + .map-wrapper { + .searchbox { + box-sizing: border-box; + border: 1px solid transparent; + width: 240px; + height: 32px; + padding: 0 12px; + border-radius: 3px; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); + font-size: 14px; + outline: none; + text-overflow: ellipses; + position: absolute; + left: 50%; + margin-left: -120px; + } + } + } +} -- cgit v1.2.3-70-g09d2 From b3f81bf0cad1f7dadf47de7b7fc673b35180c46c Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 30 Jul 2021 08:00:49 -0400 Subject: set default native width for maps. changed map css so sidebar will show up. fixed pointerEvents for map --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/nodes/MapBox/MapBox.scss | 3 +++ src/client/views/nodes/MapBox/MapBox.tsx | 30 ++++++++++++++++-------------- 3 files changed, 20 insertions(+), 15 deletions(-) (limited to 'src/client/views/nodes/MapBox/MapBox.scss') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index adc66c916..27bef915d 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -458,7 +458,7 @@ export class CurrentUserUtils { doc.emptyWebpage = Docs.Create.WebDocument("", { title: "webpage", _nativeWidth: 850, isTemplateDoc: true, _height: 512, _width: 400, useCors: true, system: true, cloneFieldFilter: new List(["system"]) }); } if (doc.emptyMap === undefined) { - doc.emptyMap = Docs.Create.MapDocument([], { title: "map", _width: 800, _height: 600, system: true, cloneFieldFilter: new List(["system"]) }); + doc.emptyMap = Docs.Create.MapDocument([], { title: "map", _showSidebar: true, _width: 800, _height: 600, system: true, cloneFieldFilter: new List(["system"]) }); ((doc.emptyMap as Doc).proto as Doc)["dragFactory-count"] = 0; } if (doc.activeMobileMenu === undefined) { diff --git a/src/client/views/nodes/MapBox/MapBox.scss b/src/client/views/nodes/MapBox/MapBox.scss index 863907aaf..04e8b0dd5 100644 --- a/src/client/views/nodes/MapBox/MapBox.scss +++ b/src/client/views/nodes/MapBox/MapBox.scss @@ -2,16 +2,19 @@ width: 100%; height: 100%; overflow: hidden; + display: flex; .MapBox-contents { width: 100%; height: 100%; overflow: hidden; + display: flex; > div { position: unset !important; // when the sidebar filter flys out, this prevents the map from extending outside the document box } .map-wrapper { + width: 100%; .searchbox { box-sizing: border-box; border: 1px solid transparent; diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index d52b91908..775cf03ca 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -1,22 +1,17 @@ -import { Autocomplete, GoogleMap, GoogleMapProps, InfoBox, InfoWindow, Marker } from '@react-google-maps/api'; -import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx'; +import { Autocomplete, GoogleMap, GoogleMapProps, InfoWindow, Marker } from '@react-google-maps/api'; +import { action, IReactionDisposer, observable } from 'mobx'; import { observer } from "mobx-react"; import * as React from "react"; -import { Doc, WidthSym } from '../../../../fields/Doc'; +import { Doc, WidthSym, HeightSym } from '../../../../fields/Doc'; import { documentSchema } from '../../../../fields/documentSchemas'; import { makeInterface } from '../../../../fields/Schema'; -import { Cast, NumCast, StrCast } from '../../../../fields/Types'; -import { setupMoveUpEvents, emptyFunction } from '../../../../Utils'; +import { NumCast } from '../../../../fields/Types'; +import { emptyFunction, setupMoveUpEvents } from '../../../../Utils'; import { DragManager } from '../../../util/DragManager'; -import { undoBatch } from '../../../util/UndoManager'; -import { CollectionViewType } from '../../collections/CollectionView'; -import { TabDocView } from '../../collections/TabDocView'; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent'; import { SidebarAnnos } from '../../SidebarAnnos'; -import { StyleProp } from '../../StyleProvider'; import { FieldView, FieldViewProps } from '../FieldView'; -import { PresMovement } from '../PresBox'; -import "./MapBox.scss" +import "./MapBox.scss"; import { MapMarker } from './MapMarker'; type MapDocument = makeInterface<[typeof documentSchema]>; @@ -87,6 +82,15 @@ export class MapBox extends ViewBoxAnnotatableComponent(); private _ref: React.RefObject = React.createRef(); + constructor(props: any) { + super(props); + + if (!Doc.NativeWidth(this.dataDoc)) { + Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(this.dataDoc) || 850); + Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(this.dataDoc) || this.Document[HeightSym]() / this.Document[WidthSym]() * 850); + } + } + @action private setSearchBox = (searchBox: any) => { @@ -239,12 +243,10 @@ export class MapBox extends ViewBoxAnnotatableComponent {/* HELLO WORLD! */}
e.stopPropagation()} onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()} > {/* // {/* Date: Fri, 30 Jul 2021 08:44:42 -0400 Subject: added sidebar button to mapBox --- src/client/views/SidebarAnnos.tsx | 7 +- src/client/views/nodes/MapBox/MapBox.scss | 19 +++- src/client/views/nodes/MapBox/MapBox.tsx | 101 +++++++++++++-------- src/client/views/nodes/PDFBox.tsx | 1 + src/client/views/nodes/WebBox.tsx | 1 + .../views/nodes/formattedText/FormattedTextBox.tsx | 1 + 6 files changed, 85 insertions(+), 45 deletions(-) (limited to 'src/client/views/nodes/MapBox/MapBox.scss') diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index c5ae82c61..8b063b02f 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -23,6 +23,7 @@ interface ExtraProps { layoutDoc: Doc; rootDoc: Doc; dataDoc: Doc; + usePanelWidth: boolean; whenChildContentsActiveChanged: (isActive: boolean) => void; ScreenToLocalTransform: () => Transform; sidebarAddDocument: (doc: (Doc | Doc[]), suffix: string) => boolean; @@ -70,7 +71,9 @@ export class SidebarAnnos extends React.Component { sidebarKey = () => this.props.fieldKey + "-sidebar"; filtersHeight = () => 38; screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(Doc.NativeWidth(this.props.dataDoc), 0).scale(this.props.scaling?.() || 1); - panelWidth = () => !this.props.layoutDoc._showSidebar ? 0 : this.props.layoutDoc.type === DocumentType.RTF ? this.props.PanelWidth() : (NumCast(this.props.layoutDoc.nativeWidth) - Doc.NativeWidth(this.props.dataDoc)) * this.props.PanelWidth() / NumCast(this.props.layoutDoc.nativeWidth); + panelWidth = () => !this.props.layoutDoc._showSidebar ? 0 : + this.props.usePanelWidth ? this.props.PanelWidth() : + (NumCast(this.props.layoutDoc.nativeWidth) - Doc.NativeWidth(this.props.dataDoc)) * this.props.PanelWidth() / NumCast(this.props.layoutDoc.nativeWidth); panelHeight = () => this.props.PanelHeight() - this.filtersHeight(); addDocument = (doc: Doc | Doc[]) => this.props.sidebarAddDocument(doc, this.sidebarKey()); moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.props.moveDocument(doc, targetCollection, addDocument, this.sidebarKey()); @@ -99,7 +102,7 @@ export class SidebarAnnos extends React.Component {
; }; return !this.props.layoutDoc._showSidebar ? (null) : -
{ this.searchBox = searchBox; @@ -166,19 +161,10 @@ export class MapBox extends ViewBoxAnnotatableComponent { - const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]); - const ratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? 250 : 0) + nativeWidth) / nativeWidth; - const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth); - this.layoutDoc.nativeWidth = nativeWidth * ratio; - this.layoutDoc._width = this.layoutDoc[WidthSym]() * nativeWidth * ratio / curNativeWidth; - this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth; - }); - - sidebarWidth = () => { - !this.layoutDoc._showSidebar ? 0 : - (NumCast(this.layoutDoc.nativeWidth) - Doc.NativeWidth(this.dataDoc)) * this.props.PanelWidth() / NumCast(this.layoutDoc.nativeWidth); - } + sidebarWidth = () => Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth(); + @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); } + @computed get sidebarColor() { return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "#e4e4e4")); } + @action private handlePlaceChanged = () => { @@ -242,18 +228,48 @@ export class MapBox extends ViewBoxAnnotatableComponent d?.author).length; + return (!annotated && !this.isContentActive()) ? (null) :
; + } + @action + toggleSidebar = () => { + const prevWidth = this.sidebarWidth(); + 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); + } + sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => { + const bounds = this._ref.current!.getBoundingClientRect(); + this.layoutDoc._sidebarWidthPercent = "" + 100 * Math.max(0, (1 - (e.clientX - bounds.left) / bounds.width)) + "%"; + this.layoutDoc._showSidebar = this.layoutDoc._sidebarWidthPercent !== "0%"; + e.preventDefault(); + return false; + } + render() { - return
+ return
{/* HELLO WORLD! */} -
e.stopPropagation()} onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()} > {/* // {/* */} -
+
{/* {/* */} - -
-
; +
+ +
+ {this.sidebarHandle} +
+
; } - } \ No newline at end of file diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 59f069c3d..5f82650da 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -281,6 +281,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent Date: Fri, 30 Jul 2021 09:03:53 -0400 Subject: from last --- src/client/views/nodes/MapBox/MapBox.scss | 8 -- src/client/views/nodes/MapBox/MapBox.tsx | 142 ++++++++++++++---------------- src/client/views/nodes/WebBox.tsx | 2 +- 3 files changed, 69 insertions(+), 83 deletions(-) (limited to 'src/client/views/nodes/MapBox/MapBox.scss') diff --git a/src/client/views/nodes/MapBox/MapBox.scss b/src/client/views/nodes/MapBox/MapBox.scss index e329af15c..4fae8d8ff 100644 --- a/src/client/views/nodes/MapBox/MapBox.scss +++ b/src/client/views/nodes/MapBox/MapBox.scss @@ -1,11 +1,4 @@ .mapBox { - width: 100%; - height: 100%; - overflow: hidden; - display: flex; - - - .mapBox-contents { width: 100%; height: 100%; overflow: hidden; @@ -44,5 +37,4 @@ border-radius: 20px; cursor:grabbing; } - } } diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 2d53116f3..2b3bcb0a2 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -255,88 +255,82 @@ export class MapBox extends ViewBoxAnnotatableComponent - {/* HELLO WORLD! */} -
e.stopPropagation()} - onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()} > - {/* // {/* + {/* // {/* */} -
- this.loadHandler(map)} - options={mapOptions} - > - - - - - {this.childDocs.map(place => ( - this.markerLoadHandler(marker, place)} - onClick={e => this.markerClickHandler(e, place)} - /> - ))} - {this.infoWindowOpen && this.selectedPlace && ( - -
-
+
e.stopPropagation()} + onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()} + style={{ width: `calc(100% - ${this.sidebarWidthPercent})` }}> + this.loadHandler(map)} + options={mapOptions} + > + + + + + {this.childDocs.map(place => ( + this.markerLoadHandler(marker, place)} + onClick={e => this.markerClickHandler(e, place)} + /> + ))} + {this.infoWindowOpen && this.selectedPlace && ( + +
+
+
+ +
+
+
+
+
+ +
+
- -
-
-
-
-
- -
-
-
- -
+
- - )} - -
- {/* {/* */} -
- -
- {this.sidebarHandle} +
+ + )} + +
+ {/* {/* */} +
+
+ {this.sidebarHandle}
; } } \ No newline at end of file diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index ffa6593e5..acf50e773 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -487,7 +487,7 @@ export class WebBox extends ViewBoxAnnotatableComponent +
-- 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/client/views/nodes/MapBox/MapBox.scss') 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 639eb465369f89dc541dfbeeaed34dfe133a8810 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 7 Dec 2021 11:23:36 -0500 Subject: restored keeping properties pane open when selection changes. added Doc paraemter to fitWidth() prop function. split MapBoxInfoWindow out of MapBox and added an Add Note button. --- src/client/util/SelectionManager.ts | 5 +- .../views/collections/CollectionStackingView.tsx | 12 +- src/client/views/collections/CollectionView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 4 +- src/client/views/nodes/MapBox/MapBox.scss | 7 + src/client/views/nodes/MapBox/MapBox.tsx | 194 +++++++-------------- src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx | 86 +++++++++ 7 files changed, 162 insertions(+), 148 deletions(-) create mode 100644 src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx (limited to 'src/client/views/nodes/MapBox/MapBox.scss') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 6674f684d..b71086561 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -44,11 +44,8 @@ export namespace SelectionManager { } @action DeselectAll(): void { - if (CurrentUserUtils.propertiesWidth > 0) { - CurrentUserUtils.propertiesWidth = 0; - } manager.SelectedSchemaDocument = undefined; - Array.from(manager.SelectedViews.keys()).map(dv => dv.props.whenChildContentsActiveChanged(false)); + Array.from(manager.SelectedViews.keys()).forEach(dv => dv.props.whenChildContentsActiveChanged(false)); manager.SelectedViews.clear(); } } diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index bffaf86b1..eddb97878 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -231,8 +231,8 @@ export class CollectionStackingView extends CollectionSubView lim === 0 ? this.props.PanelWidth() : lim === -1 ? 10000 : lim)(NumCast(this.layoutDoc.childLimitHeight, -1)); - const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._fitWidth || this.props.childFitWidth?.()) ? d[WidthSym]() : 0); - const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._fitWidth || this.props.childFitWidth?.()) ? d[HeightSym]() : 0); + const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._fitWidth || this.props.childFitWidth?.(d)) ? d[WidthSym]() : 0); + const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._fitWidth || this.props.childFitWidth?.(d)) ? d[HeightSym]() : 0); if (nw && nh) { const colWid = this.columnWidth / (this.isStackingView ? this.numGroupColumns : 1); const docWid = this.layoutDoc._columnsFill ? colWid : Math.min(this.getDocWidth(d), colWid); @@ -291,7 +291,7 @@ export class CollectionStackingView extends CollectionSubView JSX.Element[]) | React.ReactNode; childDocuments?: Doc[]; // used to override the documents shown by the sub collection to an explicit list (see LinkBox) childDocumentsActive?: () => boolean;// whether child documents can be dragged if collection can be dragged (eg., in a when a Pile document is in startburst mode) - childFitWidth?: () => boolean; + childFitWidth?: (child: Doc) => boolean; childShowTitle?: () => string; childOpacity?: () => number; childContextMenuItems?: () => { script: ScriptField, label: string }[]; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 138bad9b8..9fc4b7890 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -118,7 +118,7 @@ export interface DocumentViewSharedProps { layerProvider: undefined | ((doc: Doc, assign?: boolean) => boolean); styleProvider: Opt; focus: DocFocusFunc; - fitWidth?: () => boolean; + fitWidth?: (doc: Doc) => boolean; docFilters: () => string[]; docRangeFilters: () => string[]; searchFilterDocs: () => Doc[]; @@ -1140,7 +1140,7 @@ export class DocumentView extends React.Component { get ComponentView() { return this.docView?._componentView; } get allLinks() { return this.docView?.allLinks || []; } get LayoutFieldKey() { return this.docView?.LayoutFieldKey || "layout"; } - get fitWidth() { return this.props.fitWidth?.() || this.layoutDoc.fitWidth; } + get fitWidth() { return this.props.fitWidth?.(this.rootDoc) || this.layoutDoc.fitWidth; } @computed get docViewPath() { return this.props.docViewPath ? [...this.props.docViewPath(), this] : [this]; } @computed get layoutDoc() { return Doc.Layout(this.Document, this.props.LayoutTemplate?.()); } diff --git a/src/client/views/nodes/MapBox/MapBox.scss b/src/client/views/nodes/MapBox/MapBox.scss index f275bed54..1714fcaa9 100644 --- a/src/client/views/nodes/MapBox/MapBox.scss +++ b/src/client/views/nodes/MapBox/MapBox.scss @@ -8,6 +8,13 @@ position: unset !important; // when the sidebar filter flys out, this prevents the map from extending outside the document box } + .mapBox-infoWindow { + background-color: white; + opacity: 0.75; + padding: 12; + font-size: 17; + } + .mapBox-overlayButton-sidebar { background: #121721; height: 25px; diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 7875060e2..8b23405d8 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -1,5 +1,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Autocomplete, GoogleMap, GoogleMapProps, InfoWindow, LoadScript, Marker } from '@react-google-maps/api'; +import { Autocomplete, GoogleMap, GoogleMapProps, Marker } from '@react-google-maps/api'; +import * as dotenv from 'dotenv'; import { action, computed, IReactionDisposer, observable, ObservableMap } from 'mobx'; import { observer } from "mobx-react"; import * as React from "react"; @@ -10,16 +11,12 @@ import { InkTool } from '../../../../fields/InkField'; import { makeInterface } from '../../../../fields/Schema'; import { NumCast, StrCast } from '../../../../fields/Types'; import { TraceMobx } from '../../../../fields/util'; -import { emptyFunction, OmitKeys, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents, Utils } from '../../../../Utils'; +import { emptyFunction, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils'; import { Docs } from '../../../documents/Documents'; import { CurrentUserUtils } from '../../../util/CurrentUserUtils'; import { DragManager } from '../../../util/DragManager'; -import { SelectionManager } from '../../../util/SelectionManager'; import { SnappingManager } from '../../../util/SnappingManager'; -import { undoBatch } from '../../../util/UndoManager'; import { CollectionFreeFormView, MarqueeOptionsMenu } from '../../collections/collectionFreeForm'; -import { CollectionStackingView } from '../../collections/CollectionStackingView'; -import { CollectionViewType } from '../../collections/CollectionView'; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent'; import { Colors } from '../../global/globalEnums'; import { MarqueeAnnotator } from '../../MarqueeAnnotator'; @@ -28,8 +25,8 @@ import { Annotation } from '../../pdf/Annotation'; import { SidebarAnnos } from '../../SidebarAnnos'; import { StyleProp } from '../../StyleProvider'; import { FieldView, FieldViewProps } from '../FieldView'; -import * as dotenv from 'dotenv'; import "./MapBox.scss"; +import { MapBoxInfoWindow } from './MapBoxInfoWindow'; /** * MapBox architecture: @@ -146,7 +143,6 @@ export class MapBox extends ViewBoxAnnotatableComponent { - console.log('map bound is:' + this.bounds); this.allMapMarkers.map(place => { this.bounds.extend({ lat: NumCast(place.lat), lng: NumCast(place.lng) }); }); @@ -232,7 +228,7 @@ export class MapBox extends ViewBoxAnnotatableComponent { + (position: Position) => { const pos = { lat: position.coords.latitude, lng: position.coords.longitude, @@ -243,17 +239,13 @@ export class MapBox extends ViewBoxAnnotatableComponent { - console.log("add marker map status:" + this.toggleAddMarker); + this._map.addListener('click', (e: MouseEvent) => { if (this.toggleAddMarker == true) { - this.placeMarker(e.latLng, map) - console.log(this.allMapMarkers) + this.placeMarker((e as any).latLng, map); } }) } @@ -266,9 +258,6 @@ export class MapBox extends ViewBoxAnnotatableComponent { place[Id] ? this.markerMap[place[Id]] = marker : null; - - console.log("the following is a markerMap from id to Marker:") - console.log(this.markerMap); } /** @@ -277,15 +266,10 @@ export class MapBox extends ViewBoxAnnotatableComponent { + private markerClickHandler = (e: google.maps.MapMouseEvent, place: Doc) => { // set which place was clicked this.selectedPlace = place; - - console.log("you have selected this location:"); - console.log(this.selectedPlace); - place.infoWindowOpen = true; - console.log("open infowindow") } /** @@ -406,15 +390,6 @@ export class MapBox extends ViewBoxAnnotatableComponent { - if (place.infoWindowOpen) { - place.infoWindowOpen = false; - } - place.infoWindowOpen = false; - } - /** * Handles toggle of sidebar on click the little comment button */ @@ -476,19 +451,16 @@ export class MapBox extends ViewBoxAnnotatableComponent this.props.isContentActive() && this.props.pointerEvents !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" : SnappingManager.GetIsDragging() ? undefined : "none"; - @computed get annotationLayer() { - TraceMobx(); - const pe = this.pointerEvents(); + const pe = this.props.isContentActive() && this.props.pointerEvents !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" : + SnappingManager.GetIsDragging() ? undefined : "none" return
{this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno => - )} + )}
; - } - getAnchor = () => { const anchor = AnchorMenu.Instance?.GetAnchor(this._savedAnnotations) ?? @@ -496,43 +468,6 @@ export class MapBox extends ViewBoxAnnotatableComponent this.props.PanelWidth() / 5; - infoHeight = () => this.props.PanelWidth() / 5; - - // Collection stacking view for documents in the infowindow of a map marker - private renderChildDocs = (selectedDoc: Doc) => { - return
-
; - } - /** * render contents in allMapMarkers (e.g. images with exifData) into google maps as map marker * @returns @@ -543,41 +478,17 @@ export class MapBox extends ViewBoxAnnotatableComponent this.markerLoadHandler(marker, place)} - onClick={e => this.markerClickHandler(e, place)} + onClick={(e: google.maps.MapMouseEvent) => this.markerClickHandler(e, place)} /> )) } - /** - * Renders infowindow corresponding to a map marker document - * @param place - * @returns - */ - private renderInfoWindow = (place: Doc) => { - - return place.infoWindowOpen && ( - this.handleInfoWindowClose(place)} - > -
- {this.renderChildDocs(place)} -
-
- -
-
-
- ) - } - // TODO: auto center on select a document in the sidebar private handleMapCenter = (map: google.maps.Map) => { - console.log("print the selected views in selectionManager:") - if (SelectionManager.Views().lastElement()) { - console.log(SelectionManager.Views().lastElement()); - } + // console.log("print the selected views in selectionManager:") + // if (SelectionManager.Views().lastElement()) { + // console.log(SelectionManager.Views().lastElement()); + // } } panelWidth = () => this.props.PanelWidth() / (this.props.scaling?.() || 1) - this.sidebarWidth(); // (this.Document.scrollHeight || Doc.NativeHeight(this.Document) || 0); @@ -585,35 +496,41 @@ export class MapBox extends ViewBoxAnnotatableComponent this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop)); transparentFilter = () => [...this.props.docFilters(), Utils.IsTransparentFilter()]; opaqueFilter = () => [...this.props.docFilters(), Utils.IsOpaqueFilter()]; - + infoWidth = () => this.props.PanelWidth() / 5; + infoHeight = () => this.props.PanelHeight() / 5; anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; render() { - const renderAnnotations = (docFilters?: () => string[]) => - ; + const renderAnnotations = (docFilters?: () => string[]) => (null); + // bcz: commmented this out. Otherwise, any documents that are rendered with an InfoWindow of a marker + // will also be rendered as freeform annotations on the map. However, it doesn't seem that rendering + // freeform documents on the map does anything anyway, so getting rid of it for now. Also, since documents + // are rendered twice, adding a new note to the InfoWindow loses focus immediately on creation since it gets + // shifted to the non-visible view of the document in this freeform view. + // ; return
- {console.log(apiKey)} + {/*console.log(apiKey)*/} {/* {this.renderMarkers()} - {this.allMapMarkers.map(place => ( - this.renderInfoWindow(place) - ))} + {this.allMapMarkers.filter(marker => marker.infoWindowOpen).map(marker => )} {this.handleMapCenter(this._map)} {!this._marqueeing || !this._mainCont.current || !this._annotationLayer.current ? (null) : @@ -688,4 +612,4 @@ export class MapBox extends ViewBoxAnnotatableComponent
; } -} \ No newline at end of file +} diff --git a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx new file mode 100644 index 000000000..e6f98e5cf --- /dev/null +++ b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx @@ -0,0 +1,86 @@ +import { InfoWindow } from '@react-google-maps/api'; +import { action, computed } from 'mobx'; +import { observer } from "mobx-react"; +import * as React from "react"; +import { Doc } from '../../../../fields/Doc'; +import { Id } from '../../../../fields/FieldSymbols'; +import { emptyFunction, OmitKeys, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents } from '../../../../Utils'; +import { Docs } from '../../../documents/Documents'; +import { DocumentType } from '../../../documents/DocumentTypes'; +import { CollectionStackingView } from '../../collections/CollectionStackingView'; +import { CollectionViewType } from '../../collections/CollectionView'; +import { ViewBoxAnnotatableProps } from '../../DocComponent'; +import { FieldViewProps } from '../FieldView'; +import { FormattedTextBox } from '../formattedText/FormattedTextBox'; +import "./MapBox.scss"; + + +interface MapBoxInfoWindowProps { + place: Doc; + renderDepth: number; + markerMap: { [id: string]: google.maps.Marker }; + isAnyChildContentActive: () => boolean; +} +@observer +export class MapBoxInfoWindow extends React.Component{ + + @action + private handleInfoWindowClose = () => { + if (this.props.place.infoWindowOpen) { + this.props.place.infoWindowOpen = false; + } + this.props.place.infoWindowOpen = false; + } + + addNoteClick = (e: React.PointerEvent) => { + setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => { + const newBox = Docs.Create.TextDocument("Note", { _autoHeight: true }); + FormattedTextBox.SelectOnLoad = newBox[Id];// track the new text box so we can give it a prop that tells it to focus itself when it's displayed + Doc.AddDocToList(this.props.place, "data", newBox); + e.stopPropagation(); + e.preventDefault(); + }); + } + + // Collection stacking view for documents in the infowindow of a map marker + @computed get renderChildDocs() { + return; + } + render() { + return +
+
+ doc.type === DocumentType.RTF} + // childDocumentsActive={returnFalse} + removeDocument={(doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((p, d) => p && Doc.RemoveDocFromList(this.props.place, "data", d), true as boolean)} + addDocument={(doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((p, d) => p && Doc.AddDocToList(this.props.place, "data", d), true as boolean)} + renderDepth={this.props.renderDepth + 1} + viewType={CollectionViewType.Stacking} + pointerEvents="all" + /> +
+
+
{ e.stopPropagation(); e.preventDefault(); }} > + Add Note +
+
+
; + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From f1d0a1f3849971be805924915a4ace7fecc55bda Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 8 Dec 2021 22:22:43 -0500 Subject: tried to simplify the mapbox ui. --- src/client/views/PropertiesButtons.tsx | 3 +- src/client/views/nodes/MapBox/MapBox.scss | 26 +++++- src/client/views/nodes/MapBox/MapBox.tsx | 139 ++++++++++++++++++++---------- 3 files changed, 117 insertions(+), 51 deletions(-) (limited to 'src/client/views/nodes/MapBox/MapBox.scss') diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 378c67253..f9dab9f82 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -206,6 +206,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { const layoutField = this.selectedDoc?.[Doc.LayoutFieldKey(this.selectedDoc)]; const isText = layoutField instanceof RichTextField; const isInk = layoutField instanceof InkField; + const isMap = this.selectedDoc?.type === DocumentType.MAP; const isCollection = this.selectedDoc?.type === DocumentType.COL; const isStacking = this.selectedDoc?._viewType === CollectionViewType.Stacking; const isFreeForm = this.selectedDoc?._viewType === CollectionViewType.Freeform; @@ -221,7 +222,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { {toggle(this.dictationButton, { display: isNovice ? "none" : "" })} {toggle(this.onClickButton)} {toggle(this.fitWidthButton)} - {toggle(this.fitContentButton, { display: !isFreeForm ? "none" : "" })} + {toggle(this.fitContentButton, { display: !isFreeForm && !isMap ? "none" : "" })} {toggle(this.autoHeightButton, { display: !isText && !isStacking && !isTree ? "none" : "" })} {toggle(this.maskButton, { display: !isInk ? "none" : "" })} {toggle(this.chromeButton, { display: !isCollection || isNovice ? "none" : "" })} diff --git a/src/client/views/nodes/MapBox/MapBox.scss b/src/client/views/nodes/MapBox/MapBox.scss index 1714fcaa9..854da5ed2 100644 --- a/src/client/views/nodes/MapBox/MapBox.scss +++ b/src/client/views/nodes/MapBox/MapBox.scss @@ -4,9 +4,6 @@ height: 100%; overflow: hidden; display: flex; - > div { - position: unset !important; // when the sidebar filter flys out, this prevents the map from extending outside the document box - } .mapBox-infoWindow { background-color: white; @@ -56,7 +53,6 @@ } .mapBox-sidebar-handle { - position: absolute !important; top: 0; //top: calc(50% - 17.5px); // use this to center vertically -- make sure it looks okay for slide views width: 10px; @@ -66,4 +62,26 @@ border-radius: 20px; cursor:grabbing; } + .mapBox-addMarker { + left: 50%; + margin-left: 120px; + right: unset !important; + margin-top: -10; + height: max-content; + } + .searchbox { + display:none; + } + .mapBox-addMarker { + display:none; + } +} + +.mapBox:hover { + .mapBox-addMarker { + display:block; + } + .searchbox { + display :block; + } } diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 8b23405d8..fc656cd37 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -110,10 +110,8 @@ export class MapBox extends ViewBoxAnnotatableComponent(); @observable private searchMarkers: google.maps.Marker[] = []; @observable private searchBox = new window.google.maps.places.Autocomplete(this.inputRef.current!, options); @@ -143,10 +141,12 @@ export class MapBox extends ViewBoxAnnotatableComponent { - this.allMapMarkers.map(place => { - this.bounds.extend({ lat: NumCast(place.lat), lng: NumCast(place.lng) }); - }); - map.fitBounds(this.bounds) + const curBounds = map.getBounds() ?? new window.google.maps.LatLngBounds(); + const isFitting = this.allMapMarkers.reduce((fits, place) => + fits && curBounds?.contains({ lat: NumCast(place.lat), lng: NumCast(place.lng) }), true as boolean); + !isFitting && map.fitBounds(this.allMapMarkers.reduce((bounds, place) => + bounds.extend({ lat: NumCast(place.lat), lng: NumCast(place.lng) }), + new window.google.maps.LatLngBounds())); } /** @@ -154,31 +154,51 @@ export class MapBox extends ViewBoxAnnotatableComponent { + 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.border = "2px solid #fff"; controlUI.style.borderRadius = "3px"; controlUI.style.cursor = "pointer"; - controlUI.style.marginTop = "8px"; + controlUI.style.marginTop = "10px"; + controlUI.style.borderRadius = "4px"; controlUI.style.marginBottom = "22px"; controlUI.style.textAlign = "center"; - controlUI.title = "Click to add marker to the location your pointer is at"; - controlDiv.appendChild(controlUI); + 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 controlText = document.createElement("div"); - - controlText.style.color = "rgb(25,25,25)"; - controlText.style.fontFamily = "Roboto,Arial,sans-serif"; - controlText.style.fontSize = "16px"; - controlText.style.lineHeight = "38px"; - controlText.style.paddingLeft = "5px"; - controlText.style.paddingRight = "5px"; - controlText.innerHTML = "Add Marker"; - controlUI.appendChild(controlText); + 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", () => { @@ -186,14 +206,16 @@ export class MapBox extends ViewBoxAnnotatableComponent { this._map = map; - const centerControlDiv = document.createElement("div"); - this.CenterControl(centerControlDiv); + 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.") - }; - this.fitBounds(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.fitToBox && this.fitBounds(this._map); + } + }, 250); // listener to addmarker event this._map.addListener('click', (e: MouseEvent) => { if (this.toggleAddMarker == true) { @@ -250,6 +278,25 @@ export class MapBox extends ViewBoxAnnotatableComponent { + if (this._loadPending && this._map.getBounds()) { + this._loadPending = false; + this.layoutDoc.fitToBox && this.fitBounds(this._map); + } + this.dataDoc.mapLat = this._map.getCenter()?.lat(); + this.dataDoc.mapLng = this._map.getCenter()?.lng(); + } + + @action + zoomChanged = () => { + if (this._loadPending && this._map.getBounds()) { + this._loadPending = false; + this.layoutDoc.fitToBox && this.fitBounds(this._map); + } + this.dataDoc.mapZoom = this._map.getZoom(); + } + /** * Load and render all map markers * @param marker @@ -361,7 +408,6 @@ export class MapBox extends ViewBoxAnnotatableComponent this.loadHandler(map)} + onZoomChanged={this.zoomChanged} + onCenterChanged={this.centered} + onLoad={this.loadHandler} options={mapOptions} >