From e17b1bdb09bfcadc717e687b09d2c18596341a10 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 9 Feb 2023 21:15:58 -0500 Subject: fixed childLayoutString to work. made images capable of fitWidth. fixed animating data field pres changes. fixed lightbox to ignore annotations on collections. fixed double-click on icon to open in lightbox. added options for turning off ink labels, and opening ink in lightbox. fixed closing ink strokes by dragging. fixed drawing ink to use coord sys of starting point and to render ink the correct width and to honor GestureOverlay mode properly. . --- src/client/views/nodes/DocumentView.tsx | 21 ++++--- src/client/views/nodes/ImageBox.tsx | 73 +++++++++++++++++----- src/client/views/nodes/LinkAnchorBox.tsx | 1 + src/client/views/nodes/MapBox/MapBox.tsx | 4 +- src/client/views/nodes/WebBox.tsx | 11 ++-- .../views/nodes/formattedText/FormattedTextBox.tsx | 1 - src/client/views/nodes/trails/PresBox.tsx | 4 ++ 7 files changed, 81 insertions(+), 34 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index b94db2c6b..36c0240f1 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -56,6 +56,7 @@ import { ScriptingBox } from './ScriptingBox'; import { PresEffect, PresEffectDirection } from './trails'; import { PinProps } from './trails/PresBox'; import React = require('react'); +import { GestureOverlay } from '../GestureOverlay'; const { Howl } = require('howler'); interface Window { @@ -139,7 +140,6 @@ export interface DocComponentView { fieldKey?: string; annotationKey?: string; getTitle?: () => string; - getScrollHeight?: () => number; getCenter?: (xf: Transform) => { X: number; Y: number }; ptToScreen?: (pt: { X: number; Y: number }) => { X: number; Y: number }; ptFromScreen?: (pt: { X: number; Y: number }) => { X: number; Y: number }; @@ -170,7 +170,7 @@ export interface DocumentViewSharedProps { dataTransition?: string; // specifies animation transition - used by collectionPile and potentially other layout engines when changing the size of documents so that the change won't be abrupt styleProvider: Opt; focus: DocFocusFunc; - fitWidth?: (doc: Doc) => boolean; + fitWidth?: (doc: Doc) => boolean | undefined; docFilters: () => string[]; docRangeFilters: () => string[]; searchFilterDocs: () => Doc[]; @@ -637,8 +637,8 @@ export class DocumentViewInternal extends DocComponent (func().result?.select === true ? this.props.select(false) : ''), 'on double click'); - } else if (!Doc.IsSystem(this.rootDoc) && !this.rootDoc.isLinkButton) { - UndoManager.RunInBatch(() => LightboxView.AddDocTab(this.rootDoc, OpenWhere.lightbox, this.props.LayoutTemplate?.(), this.props.addDocTab), 'double tap'); + } else if (!Doc.IsSystem(this.rootDoc) && (![DocumentType.INK].includes(this.rootDoc.type as any) || Doc.UserDoc().openInkInLightbox) && !this.rootDoc.isLinkButton) { + UndoManager.RunInBatch(() => LightboxView.AddDocTab(this.rootDoc, OpenWhere.lightbox, this.props.LayoutTemplate?.()), 'double tap'); SelectionManager.DeselectAll(); Doc.UnBrushDoc(this.props.Document); } @@ -669,7 +669,7 @@ export class DocumentViewInternal extends DocComponent { this._timeout = undefined; clickFunc(); - }, 350); + }, 150); } else clickFunc(); } else if (!this._longPress && this.allLinks.length && this.Document.type !== DocumentType.LINK && !isScriptBox() && this.Document.isLinkButton && !e.shiftKey && !e.ctrlKey) { SelectionManager.DeselectAll(); @@ -698,6 +698,7 @@ export class DocumentViewInternal extends DocComponent { + if (!(e.nativeEvent as any).DownDocView) (e.nativeEvent as any).DownDocView = GestureOverlay.DownDocView = this.props.DocumentView(); if (this.rootDoc.type === DocumentType.INK && Doc.ActiveTool === InkTool.Eraser) return; // continue if the event hasn't been canceled AND we are using a mouse or this has an onClick or onDragStart function (meaning it is a button document) if (!(InteractionUtils.IsType(e, InteractionUtils.MOUSETYPE) || [InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool))) { @@ -1640,7 +1641,7 @@ export class DocumentView extends React.Component { return this.docView?.LayoutFieldKey || 'layout'; } get fitWidth() { - return this.props.fitWidth?.(this.rootDoc) || this.layoutDoc.fitWidth; + return this.props.fitWidth?.(this.rootDoc) ?? this.layoutDoc?.fitWidth; } @computed get hideLinkButton() { @@ -1688,8 +1689,7 @@ export class DocumentView extends React.Component { } @computed get panelHeight() { if (this.effectiveNativeHeight && !this.layoutDoc.nativeHeightUnfrozen) { - const scrollHeight = this.fitWidth ? Math.max(this.ComponentView?.getScrollHeight?.() ?? NumCast(this.layoutDoc.scrollHeight)) : 0; - return Math.min(this.props.PanelHeight(), Math.max(scrollHeight, this.effectiveNativeHeight) * this.nativeScaling); + return Math.min(this.props.PanelHeight(), this.effectiveNativeHeight * this.nativeScaling); } return this.props.PanelHeight(); } @@ -1902,6 +1902,11 @@ ScriptingGlobals.add(function deiconifyView(documentView: DocumentView) { documentView.select(false); }); +ScriptingGlobals.add(function deiconifyViewToLightbox(documentView: DocumentView) { + //documentView.iconify(() => + LightboxView.AddDocTab(documentView.rootDoc, OpenWhere.lightbox, 'layout'); //, 0); +}); + ScriptingGlobals.add(function toggleDetail(dv: DocumentView, detailLayoutKeySuffix: string) { if (dv.Document.layoutKey === 'layout_' + detailLayoutKeySuffix) dv.switchViews(false, 'layout'); else dv.switchViews(true, detailLayoutKeySuffix, undefined, true); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index bdd99528b..540958941 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -11,7 +11,7 @@ import { ComputedField } from '../../../fields/ScriptField'; import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { TraceMobx } from '../../../fields/util'; -import { emptyFunction, OmitKeys, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../Utils'; +import { DashColor, emptyFunction, OmitKeys, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../Utils'; import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; import { CognitiveServices, Confidence, Service, Tag } from '../../cognitive_services/CognitiveServices'; import { Docs, DocUtils } from '../../documents/Documents'; @@ -26,13 +26,15 @@ import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComp import { MarqueeAnnotator } from '../MarqueeAnnotator'; import { AnchorMenu } from '../pdf/AnchorMenu'; import { StyleProp } from '../StyleProvider'; -import { DocFocusOptions, DocumentViewProps } from './DocumentView'; +import { DocFocusOptions, OpenWhere } from './DocumentView'; import { FaceRectangles } from './FaceRectangles'; import { FieldView, FieldViewProps } from './FieldView'; import './ImageBox.scss'; import { PresBox } from './trails'; import React = require('react'); import Color = require('color'); +import { LinkDocPreview } from './LinkDocPreview'; +import { DocumentManager } from '../../util/DocumentManager'; export const pageSchema = createSchema({ googlePhotosUrl: 'string', @@ -51,6 +53,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent>, addAsAnnotation: boolean) => Opt = () => undefined; @@ -119,6 +123,16 @@ export class ImageBox extends ViewBoxAnnotatableComponent this.layoutDoc._scrollTop, + s_top => { + this._forcedScroll = true; + !this._ignoreScroll && this._mainCont.current && (this._mainCont.current.scrollTop = NumCast(s_top)); + this._mainCont.current?.scrollTo({ top: NumCast(s_top) }); + this._forcedScroll = false; + }, + { fireImmediately: true } + ); } componentWillUnmount() { @@ -155,6 +169,21 @@ export class ImageBox extends ViewBoxAnnotatableComponent (this.layoutDoc[this.fieldKey + '-useAlt'] = !this.layoutDoc[this.fieldKey + '-useAlt']); + @undoBatch + setNativeSize = action(() => { + const scaling = (this.props.DocumentView?.().props.ScreenToLocalTransform().Scale || 1) / NumCast(this.rootDoc._viewScale, 1); + const nscale = NumCast(this.props.PanelWidth()) / scaling; + const nh = nscale / NumCast(this.dataDoc[this.fieldKey + '-nativeHeight']); + const nw = nscale / NumCast(this.dataDoc[this.fieldKey + '-nativeWidth']); + this.dataDoc[this.fieldKey + '-nativeHeight'] = NumCast(this.dataDoc[this.fieldKey + '-nativeHeight']) * nh; + this.dataDoc[this.fieldKey + '-nativeWidth'] = NumCast(this.dataDoc[this.fieldKey + '-nativeWidth']) * nw; + this.rootDoc._panX = nh * NumCast(this.rootDoc._panX); + this.rootDoc._panY = nw * NumCast(this.rootDoc._panY); + this.dataDoc._panXMax = this.dataDoc._panXMax ? nh * NumCast(this.dataDoc._panXMax) : undefined; + this.dataDoc._panXMin = this.dataDoc._panXMin ? nh * NumCast(this.dataDoc._panXMin) : undefined; + this.dataDoc._panYMax = this.dataDoc._panYMax ? nw * NumCast(this.dataDoc._panYMax) : undefined; + this.dataDoc._panYMin = this.dataDoc._panYMin ? nw * NumCast(this.dataDoc._panYMin) : undefined; + }); @undoBatch rotate = action(() => { const nw = NumCast(this.dataDoc[this.fieldKey + '-nativeWidth']); @@ -189,6 +218,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent setTimeout(() => (dv.ComponentView as ImageBox).setNativeSize(), 200)); this.props.bringToFront(cropping); return cropping; }; @@ -216,6 +250,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent Utils.CopyText(this.choosePath(field.url)), icon: 'expand-arrows-alt' }); if (!Doc.noviceMode) { @@ -282,6 +317,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent; }; + getScrollHeight = () => (this.props.fitWidth?.(this.rootDoc) !== false && NumCast(this.rootDoc._viewScale, 1) === NumCast(this.rootDoc._viewScaleMin, 1) ? this.nativeSize.nativeHeight : undefined); + @computed private get considerDownloadIcon() { const data = this.dataDoc[this.fieldKey]; @@ -346,9 +383,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent -
+
{fadepath === srcpath ? null : (
[this.content]; private _mainCont: React.RefObject = React.createRef(); @@ -394,6 +430,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent; } + screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop) * this.props.ScreenToLocalTransform().Scale); marqueeDown = (e: React.PointerEvent) => { if (!e.altKey && e.button === 0 && NumCast(this.rootDoc._viewScale, 1) <= NumCast(this.rootDoc.viewScaleMin, 1) && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) { setupMoveUpEvents( @@ -410,7 +447,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent this.nativeSize.nativeHeight; @action finishMarquee = () => { this._getAnchor = AnchorMenu.Instance?.GetAnchor; @@ -418,11 +454,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent this._savedAnnotations; - styleProvider = (doc: Opt, props: Opt, property: string): any => { - if (property === StyleProp.BoxShadow) return undefined; - return this.props.styleProvider?.(doc, props, property); - }; - render() { TraceMobx(); const borderRad = this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BorderRounding); @@ -432,25 +463,35 @@ export class ImageBox extends ViewBoxAnnotatableComponent { + if (!this._forcedScroll) { + if (this.layoutDoc._scrollTop || this._mainCont.current?.scrollTop) { + this._ignoreScroll = true; + this.layoutDoc._scrollTop = this._mainCont.current?.scrollTop; + this._ignoreScroll = false; + } + } + })} style={{ width: this.props.PanelWidth() ? undefined : `100%`, height: this.props.PanelWidth() ? undefined : `100%`, pointerEvents: this.layoutDoc._lockedPosition ? 'none' : undefined, borderRadius, - overflow: 'auto', + overflow: this.layoutDoc.fitWidth || this.props.fitWidth?.(this.rootDoc) ? 'auto' : undefined, }}> () { } else { this.rootDoc[this.fieldKey + '_x'] = ((pt[0] - bounds.left) / bounds.width) * 100; this.rootDoc[this.fieldKey + '_y'] = ((pt[1] - bounds.top) / bounds.height) * 100; + this.rootDoc.linkAutoMove = false; } } return false; diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 95cb49037..5940fc075 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -542,8 +542,8 @@ export class MapBox extends ViewBoxAnnotatableComponent this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth(); // (this.Document.scrollHeight || Doc.NativeHeight(this.Document) || 0); - panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1); // () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document); + panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth(); + panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1); scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop)); transparentFilter = () => [...this.props.docFilters(), Utils.IsTransparentFilter()]; opaqueFilter = () => [...this.props.docFilters(), Utils.IsOpaqueFilter()]; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index d0d638e98..c4cca9679 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -295,12 +295,12 @@ export class WebBox extends ViewBoxAnnotatableComponent this._scrollHeight; - isFirefox = () => { return 'InstallTrigger' in window; // navigator.userAgent.indexOf("Chrome") !== -1; }; @@ -969,8 +966,8 @@ export class WebBox extends ViewBoxAnnotatableComponent) => (this._searchString = e.currentTarget.value); showInfo = action((anno: Opt) => (this._overlayAnnoInfo = anno)); setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean) => void) => (this._setPreviewCursor = func); - panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth() + WebBox.sidebarResizerWidth; // (this.Document.scrollHeight || Doc.NativeHeight(this.Document) || 0); - panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1); // () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document); + panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth() + WebBox.sidebarResizerWidth; + panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1); scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop)); anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; transparentFilter = () => [...this.props.docFilters(), Utils.IsTransparentFilter()]; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 619c59f0e..80b18b8b9 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -994,7 +994,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent this.scrollHeight; // if the scroll height has changed and we're in autoHeight mode, then we need to update the textHeight component of the doc. // Since we also monitor all component height changes, this will update the document's height. resetNativeHeight = (scrollHeight: number) => { diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 427911bd3..0a96297b7 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -35,6 +35,7 @@ import { ScriptingBox } from '../ScriptingBox'; import './PresBox.scss'; import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums'; import { CollectionStackedTimeline } from '../../collections/CollectionStackedTimeline'; +import { PresElementBox } from './PresElementBox'; const { Howl } = require('howler'); export interface PinProps { @@ -383,9 +384,11 @@ export class PresBox extends ViewBoxBaseComponent() { Doc.GetProto(bestTarget)[fkey + '-annotations'] = new List([...DocListCast(bestTarget[fkey + '-annotations']).filter(doc => doc.unrendered), ...DocListCast(activeItem.presAnnotations)]); } if (pinDataTypes.dataview && activeItem.presData !== undefined) { + bestTarget._dataTransition = `all ${transTime}ms`; const fkey = Doc.LayoutFieldKey(bestTarget); Doc.GetProto(bestTarget)[fkey] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData; bestTarget[fkey + '-useAlt'] = activeItem.presUseAlt; + setTimeout(() => (bestTarget._dataTransition = undefined), transTime + 10); } if (pinDataTypes.textview && activeItem.presData !== undefined) Doc.GetProto(bestTarget)[Doc.LayoutFieldKey(bestTarget)] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData; if (pinDataTypes.poslayoutview) { @@ -2244,6 +2247,7 @@ export class PresBox extends ViewBoxBaseComponent() { ignoreUnrendered={true} //childFitWidth={returnTrue} childOpacity={returnOne} + //childLayoutString={PresElementBox.LayoutString('data')} childLayoutTemplate={this.childLayoutTemplate} childXPadding={Doc.IsComicStyle(this.rootDoc) ? 20 : undefined} filterAddDocument={this.addDocumentFilter} -- cgit v1.2.3-70-g09d2 From 32f5040c44dc302e3dd53cecd9be4cd51a474d3f Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 14 Feb 2023 14:57:25 -0500 Subject: fixed pinning regions on pdf/web pages to allow proper pres following. added click on pres item# to select w/o navigation. fixed dashDocView to be selectable without losing selection to parent textbox. added BingMaps rudimentary option to googleMaps --- package-lock.json | 18 ++- package.json | 2 + src/client/views/nodes/MapBox/MapBox.tsx | 148 +++++++++++++-------- src/client/views/nodes/PDFBox.tsx | 1 + src/client/views/nodes/WebBox.tsx | 1 + .../views/nodes/formattedText/DashDocView.tsx | 5 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 3 + src/client/views/nodes/trails/PresBox.tsx | 20 +-- src/client/views/nodes/trails/PresElementBox.scss | 6 + src/client/views/nodes/trails/PresElementBox.tsx | 12 +- 10 files changed, 143 insertions(+), 73 deletions(-) (limited to 'src/client/views/nodes') diff --git a/package-lock.json b/package-lock.json index 547a6e1d7..95a128419 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3675,6 +3675,11 @@ "file-uri-to-path": "1.0.0" } }, + "bingmaps-react": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/bingmaps-react/-/bingmaps-react-1.2.10.tgz", + "integrity": "sha512-fM887Sr6OIlo6ThmSpGfNEDssSytdnsMrbDTDs+YH/43etf0dlfcR4oaJvygy+fwn21hpP2lVvwTHUDZvGxZqA==" + }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -4970,9 +4975,9 @@ } }, "core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.28.0.tgz", + "integrity": "sha512-GiZn9D4Z/rSYvTeg1ljAIsEqFm0LaN9gVtwDCrKL80zHtS31p9BAjmTxVqTQDMpwlMolJZOFntUG2uwyj7DAqw==" }, "core-js-pure": { "version": "3.22.8", @@ -8260,6 +8265,13 @@ "promise": "^7.1.1", "setimmediate": "^1.0.5", "ua-parser-js": "^0.7.30" + }, + "dependencies": { + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA==" + } } }, "fd-slicer": { diff --git a/package.json b/package.json index 712354355..00ce356f9 100644 --- a/package.json +++ b/package.json @@ -165,6 +165,7 @@ "bcrypt-nodejs": "0.0.3", "bezier-curve": "^1.0.0", "bezier-js": "^4.1.1", + "bingmaps-react": "^1.2.10", "bluebird": "^3.7.2", "body-parser": "^1.19.2", "bootstrap": "^4.6.1", @@ -181,6 +182,7 @@ "connect-mongo": "^2.0.3", "cookie-parser": "^1.4.6", "cookie-session": "^2.0.0", + "core-js": "^3.28.0", "cors": "^2.8.5", "depcheck": "^0.9.2", "equation-editor-react": "github:bobzel/equation-editor-react#useLocally", diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 5940fc075..039f11cd1 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, Marker } from '@react-google-maps/api'; +import BingMapsReact from 'bingmaps-react'; import { action, computed, IReactionDisposer, observable, ObservableMap, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -43,20 +44,22 @@ const mapContainerStyle = { }; const defaultCenter = { - lat: 38.685, - lng: -115.234, + lat: 42.360081, + lng: -71.058884, }; const mapOptions = { fullscreenControl: false, }; +const bingApiKey = process.env.BING_MAPS; // if you're running local, get a Bing Maps api key here: https://www.bingmapsportal.com/ and then add it to the .env file in the Dash-Web root directory as: _CLIENT_BING_MAPS= const apiKey = process.env.GOOGLE_MAPS; const script = document.createElement('script'); script.defer = true; script.async = true; script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places,drawing`; +console.log(script.src); document.head.appendChild(script); /** @@ -84,6 +87,7 @@ const options = { @observer export class MapBox extends ViewBoxAnnotatableComponent>() { + static UseBing = true; private _dropDisposer?: DragManager.DragDropDisposer; private _disposers: { [name: string]: IReactionDisposer } = {}; private _annotationLayer: React.RefObject = React.createRef(); @@ -551,69 +555,99 @@ export class MapBox extends ViewBoxAnnotatableComponent this.props.PanelHeight() / 5; anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; savedAnnotations = () => this._savedAnnotations; + + _bingSearchManager: any; + _bingMap: any; + get MicrosoftMaps() { + return (window as any).Microsoft.Maps; + } + // uses Bing Search to retrieve lat/lng for a location. eg., + // const results = this.geocodeQuery(map.map, 'Philadelphia, PA'); + // to move the map to that location: + // const location = await this.geocodeQuery(this._bingMap, 'Philadelphia, PA'); + // this._bingMap.current.setView({ + // mapTypeId: this.MicrosoftMaps.MapTypeId.aerial, + // center: new this.MicrosoftMaps.Location(loc.latitude, loc.longitude), + // }); + // + bingGeocode = (map: any, query: string) => { + return new Promise<{ latitude: number; longitude: number }>((res, reject) => { + //If search manager is not defined, load the search module. + if (!this._bingSearchManager) { + //Create an instance of the search manager and call the geocodeQuery function again. + this.MicrosoftMaps.loadModule('Microsoft.Maps.Search', () => { + this._bingSearchManager = new this.MicrosoftMaps.Search.SearchManager(map.current); + res(this.bingGeocode(map, query)); + }); + } else { + this._bingSearchManager.geocode({ + where: query, + callback: action((r: any) => { + res(r.results[0].location); + }), + errorCallback: (e: any) => reject(), + }); + } + }); + }; + + bingViewOptions = { + center: { latitude: defaultCenter.lat, longitude: defaultCenter.lng }, + mapTypeId: 'grayscale', + }; + bingMapOptions = { + navigationBarMode: 'square', + }; + bingMapReady = (map: any) => (this._bingMap = map.map); render() { 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)*/} - {/* */} -
e.stopPropagation()} onPointerDown={e => e.button === 0 && !e.ctrlKey && e.stopPropagation()} style={{ width: `calc(100% - ${this.sidebarWidthPercent})` }}> +
e.stopPropagation()} + onPointerDown={async e => { + e.button === 0 && !e.ctrlKey && e.stopPropagation(); + // just a simple test of bing maps geocode api + // const loc = await this.bingGeocode(this._bingMap, 'Philadelphia, PA'); + // this._bingMap.current.setView({ + // mapTypeId: this.MicrosoftMaps.MapTypeId.aerial, + // center: new this.MicrosoftMaps.Location(loc.latitude, loc.longitude), + // zoom: 15, + // }); + }} + style={{ width: `calc(100% - ${this.sidebarWidthPercent})` }}>
{renderAnnotations(this.transparentFilter)}
{renderAnnotations(this.opaqueFilter)} {SnappingManager.GetIsDragging() ? null : renderAnnotations()} {this.annotationLayer} - - - e.stopPropagation()} placeholder="Enter location" /> - - - {this.renderMarkers()} - {this.allMapMarkers - .filter(marker => marker.infoWindowOpen) - .map(marker => ( - - ))} - {/* {this.handleMapCenter(this._map)} */} - + + {!MapBox.UseBing ? null : } +
+ + + e.stopPropagation()} placeholder="Enter location" /> + + + {this.renderMarkers()} + {this.allMapMarkers + .filter(marker => marker.infoWindowOpen) + .map(marker => ( + + ))} + {/* {this.handleMapCenter(this._map)} */} + +
{!this._marqueeing || !this._mainCont.current || !this._annotationLayer.current ? null : ( { Document={this._finalLayout} DataDoc={this._resolvedDataDoc} addDocument={returnFalse} - rootSelected={this._textBox.props.isSelected} + rootSelected={returnFalse} //{this._textBox.props.isSelected} removeDocument={this.removeDoc} isDocumentActive={returnFalse} - isContentActive={this._textBox.props.isContentActive} + isContentActive={emptyFunction} styleProvider={this._textBox.props.styleProvider} docViewPath={this._textBox.props.docViewPath} ScreenToLocalTransform={this.getDocTransform} diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 80b18b8b9..49acd8a57 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1487,6 +1487,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent node that wraps the hyerlink while (target && !target.dataset?.targethrefs) target = target.parentElement; FormattedTextBoxComment.update(this, editor, undefined, target?.dataset?.targethrefs, target?.dataset.linkdoc, target?.dataset.nopreview === 'true'); + if (pcords && pcords.inside > 0 && this._editorView.state.doc.nodeAt(pcords.inside)?.type === this._editorView.state.schema.nodes.dashDoc) { + return; + } } if (e.button === 0 && this.props.isSelected(true) && !e.altKey) { diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 0a96297b7..e07517113 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -14,7 +14,7 @@ import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Ty import { AudioField } from '../../../../fields/URLField'; import { emptyFunction, emptyPath, returnFalse, returnOne, setupMoveUpEvents, StopEvent } from '../../../../Utils'; import { DocServer } from '../../../DocServer'; -import { Docs } from '../../../documents/Documents'; +import { Docs, DocumentOptions } from '../../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; import { DocumentManager } from '../../../util/DocumentManager'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; @@ -869,13 +869,13 @@ export class PresBox extends ViewBoxBaseComponent() { presDocView && SelectionManager.SelectView(presDocView, false); }; + focusElement = (doc: Doc, options: DocFocusOptions) => this.selectElement(doc); + //Regular click @action - selectElement = async (doc: Doc) => { + selectElement = async (doc: Doc, noNav = false) => { CollectionStackedTimeline.CurrentlyPlaying?.map((clip, i) => DocumentManager.Instance.getDocumentView(clip)?.ComponentView?.Pause?.()); - this.gotoDocument(this.childDocs.indexOf(doc), this.activeItem); - // if (doc.presPinView) setTimeout(() => this.updateCurrentPresentation(DocCast(doc.context)), 0); - // else + !noNav && this.gotoDocument(this.childDocs.indexOf(doc), this.activeItem); this.updateCurrentPresentation(DocCast(doc.context)); }; @@ -911,19 +911,19 @@ export class PresBox extends ViewBoxBaseComponent() { //regular click @action - regularSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, focus: boolean, selectPres = true) => { + regularSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, focus: boolean, selectPres = true, noNav = false) => { this.clearSelectedArray(); this.addToSelectedArray(doc); this._eleArray.splice(0, this._eleArray.length, ref); this._dragArray.splice(0, this._dragArray.length, drag); - focus && this.selectElement(doc); + focus && this.selectElement(doc, noNav); selectPres && this.selectPres(); }; - modifierSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, focus: boolean, cmdClick: boolean, shiftClick: boolean) => { + modifierSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, focus: boolean, cmdClick: boolean, shiftClick: boolean, noNav: boolean = false) => { if (cmdClick) this.multiSelect(doc, ref, drag); else if (shiftClick) this.shiftSelect(doc, ref, drag); - else this.regularSelect(doc, ref, drag, focus); + else this.regularSelect(doc, ref, drag, focus, noNav); }; static keyEventsWrapper = (e: KeyboardEvent) => PresBox.Instance?.keyEvents(e); @@ -2253,7 +2253,7 @@ export class PresBox extends ViewBoxBaseComponent() { filterAddDocument={this.addDocumentFilter} removeDocument={returnFalse} dontRegisterView={true} - focus={this.selectElement} + focus={this.focusElement} scriptContext={this} ScreenToLocalTransform={this.getTransform} AddToMap={this.AddToMap} diff --git a/src/client/views/nodes/trails/PresElementBox.scss b/src/client/views/nodes/trails/PresElementBox.scss index 415253af1..4f95f0c1f 100644 --- a/src/client/views/nodes/trails/PresElementBox.scss +++ b/src/client/views/nodes/trails/PresElementBox.scss @@ -44,6 +44,12 @@ $slide-active: #5b9fdd; display: flex; align-items: center; + .presItem-number { + cursor: pointer; + &:hover { + background-color: $light-blue; + } + } .presItem-name { display: flex; min-width: 20px; diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 788900b46..f265c1315 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -592,7 +592,17 @@ export class PresElementBox extends ViewBoxBaseComponent() { width: `calc(100% ${this.rootDoc.presExpandInlineButton ? '- 50%' : ''} - ${this.presButtons.length * 22}px`, cursor: isSelected ? 'text' : 'grab', }}> -
{`${this.indexInPres + 1}. `}
+
{ + e.stopPropagation(); + if (this._itemRef.current && this._dragRef.current) { + this.presBoxView?.modifierSelect(activeItem, this._itemRef.current, this._dragRef.current, false, false, false, true); + } + }} + onClick={e => e.stopPropagation()}>{`${this.indexInPres + 1}. `}
StrCast(activeItem.title)} SetValue={this.onSetValue} />
{/*
{"Movement speed"}
}>
{this.transition}
*/} -- cgit v1.2.3-70-g09d2