From 0fbfb06c499d2ee52b086427cbf1c5431fadfad9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 16 Dec 2020 21:39:47 -0500 Subject: simplified DocumentView a bit more. cleaned up other code. --- src/Utils.ts | 8 ++ src/client/views/GestureOverlay.tsx | 3 +- src/client/views/PropertiesButtons.tsx | 20 +-- src/client/views/PropertiesView.tsx | 2 +- src/client/views/StyleProvider.tsx | 1 - .../CollectionFreeFormLinkView.scss | 1 - src/client/views/nodes/DocumentView.tsx | 141 ++++++--------------- src/pen-gestures/GestureUtils.ts | 1 - 8 files changed, 52 insertions(+), 125 deletions(-) (limited to 'src') diff --git a/src/Utils.ts b/src/Utils.ts index 1a00c0bfb..852a00406 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -592,6 +592,14 @@ export function lightOrDark(color: any) { } } +export function isTarget(x: number, y: number, target: HTMLDivElement | null) { + let entered = false; + for (let child = document.elementFromPoint(x, y); !entered && child; child = child.parentElement) { + entered = entered || child === target; + } + return entered; +} + export function setupMoveUpEvents( target: object, e: React.PointerEvent, diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 3f57d3eb9..524462401 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -550,8 +550,7 @@ export class GestureOverlay extends Touchable { detail: { points: this._points, gesture: GestureUtils.Gestures.Line, - bounds: B, - callbackFn: callback + bounds: B } }); target1?.dispatchEvent(ge); diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index bc3be4076..4413d28f5 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -326,20 +326,12 @@ export class PropertiesButtons extends React.Component<{}, {}> { this.selectedDoc && (this.selectedDoc.onClickBehavior = e.target.value); SelectionManager.Views().forEach(dv => { - if (value === "nothing") { - dv.docView?.noOnClick(); - } else if (value === "enterPortal") { - dv.docView?.noOnClick(); - dv.docView?.makeIntoPortal(); - } else if (value === "toggleDetail") { - dv.docView?.noOnClick(); - dv.docView?.toggleDetail(); - } else if (value === "linkInPlace") { - dv.docView?.noOnClick(); - dv.toggleFollowLink("inPlace", true, false); - } else if (value === "linkOnRight") { - dv.docView?.noOnClick(); - dv.toggleFollowLink("add:right", false, false); + dv.docView?.noOnClick(); + switch (value) { + case "enterPortal": dv.docView?.makeIntoPortal(); break; + case "toggleDetail": dv.docView?.toggleDetail(); break; + case "linkInPlace": dv.docView?.toggleFollowLink("inPlace", true, false); break; + case "linkOnRight": dv.docView?.toggleFollowLink("add:right", false, false); break; } }); } diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 32342075c..4aeb4e63a 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -119,7 +119,7 @@ export class PropertiesView extends React.Component { if (this.dataDoc && this.selectedDoc) { const ids: { [key: string]: string } = {}; const docs = SelectionManager.Views().length < 2 ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc] : - SelectionManager.Views().map(dv => this.layoutFields ? Doc.Layout(dv.layoutDoc) : dv.dataDoc); + SelectionManager.Views().map(dv => this.layoutFields ? dv.layoutDoc : dv.dataDoc); docs.forEach(doc => Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key))); const rows: JSX.Element[] = []; for (const key of Object.keys(ids).slice().sort()) { diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index dd406abed..312cfc73e 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -6,7 +6,6 @@ import { Doc, Opt, StrListCast } from "../../fields/Doc"; import { List } from '../../fields/List'; import { listSpec } from '../../fields/Schema'; import { BoolCast, Cast, NumCast, StrCast } from "../../fields/Types"; -import { returnFalse } from '../../Utils'; import { DocumentType } from '../documents/DocumentTypes'; import { CurrentUserUtils } from '../util/CurrentUserUtils'; import { SnappingManager } from '../util/SnappingManager'; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss index 8cbda310a..858719a08 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss @@ -1,7 +1,6 @@ .collectionfreeformlinkview-linkLine { stroke: black; opacity: 0.8; - pointer-events: all; stroke-width: 3px; transition: opacity 0.5s ease-in; fill: transparent; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 276ab35f1..b9ca460b9 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -10,7 +10,7 @@ import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Ty import { GetEffectiveAcl, TraceMobx } from '../../../fields/util'; import { MobileInterface } from '../../../mobile/MobileInterface'; import { GestureUtils } from '../../../pen-gestures/GestureUtils'; -import { emptyFunction, OmitKeys, returnFalse, returnVal, Utils } from "../../../Utils"; +import { emptyFunction, isTarget as hasDescendantTarget, OmitKeys, returnFalse, returnVal, Utils } from "../../../Utils"; import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; import { Docs, DocUtils } from "../../documents/Documents"; import { DocumentType } from '../../documents/DocumentTypes'; @@ -119,7 +119,6 @@ export class DocumentViewInternal extends DocComponent(); private _timeout: NodeJS.Timeout | undefined; private _dropDisposer?: DragManager.DragDropDisposer; - private _gestureEventDisposer?: GestureUtils.GestureEventDisposer; private _holdDisposer?: InteractionUtils.MultiTouchEventDisposer; protected _multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer; @@ -132,6 +131,7 @@ export class DocumentViewInternal extends DocComponent { - // continue if the event hasn't been canceled AND we are using a moues or this is has an onClick or onDragStart function (meaning it is a button document) + // 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) || Doc.GetSelectedTool() === InkTool.Highlighter || Doc.GetSelectedTool() === InkTool.Pen)) { if (!InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) { e.stopPropagation(); @@ -470,7 +468,7 @@ export class DocumentViewInternal extends DocComponent 3 || Math.abs(this._downY - e.clientY) > 3) { if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler) && (e.buttons === 1 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE))) { document.removeEventListener("pointermove", this.onPointerMove); @@ -496,24 +494,6 @@ export class DocumentViewInternal extends DocComponent { - switch (ge.gesture) { - case GestureUtils.Gestures.Line: - ge.callbackFn && ge.callbackFn(this.props.Document); - e.stopPropagation(); - break; - } - } - - @undoBatch @action - deleteClicked = (): void => { - if (CurrentUserUtils.ActiveDashboard === this.props.Document) { - alert("Can't delete the active dashboard"); - } else { - this.props.removeDocument?.(this.props.Document); - } - } - @undoBatch @action toggleFollowLink = (location: Opt, zoom: boolean, setPushpin: boolean): void => { this.Document.ignoreClick = false; @@ -553,10 +533,9 @@ export class DocumentViewInternal extends DocComponent { - this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`); - } + @undoBatch deleteClicked = () => this.props.removeDocument?.(this.props.Document); + @undoBatch toggleDetail = () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`); + @undoBatch toggleLockPosition = () => this.Document.lockedPosition = this.Document.lockedPosition ? undefined : true; @undoBatch @action drop = async (e: Event, de: DragManager.DropEvent) => { @@ -574,16 +553,6 @@ export class DocumentViewInternal extends DocComponent { - Doc.toggleNativeDimensions(this.layoutDoc, this.ContentScale, this.props.PanelWidth(), this.props.PanelHeight()); - } - - @undoBatch - toggleLockPosition = (): void => { - this.Document.lockedPosition = this.Document.lockedPosition ? undefined : true; - } - @undoBatch @action makeIntoPortal = async () => { @@ -597,14 +566,6 @@ export class DocumentViewInternal extends DocComponent { - const alias = Doc.MakeAlias(this.props.Document); - alias.x = NumCast(this.props.Document.x) + NumCast(this.props.Document._width); - alias.y = NumCast(this.props.Document.y) + 30; - this.props.addDocument?.(alias); - } - @action onContextMenu = (e?: React.MouseEvent, pageX?: number, pageY?: number) => { if (e && this.rootDoc._hideContextMenu && Doc.UserDoc().noviceMode) { @@ -618,16 +579,13 @@ export class DocumentViewInternal extends DocComponent 3 || Math.abs(this._downY - e?.clientY) > 3) { - e?.preventDefault(); - return; - } + if (!navigator.userAgent.includes("Mozilla") && (Math.abs(this._downX - e?.clientX) > 3 || Math.abs(this._downY - e?.clientY) > 3)) { + return; } - e.preventDefault(); } const cm = ContextMenu.Instance; @@ -693,7 +651,6 @@ export class DocumentViewInternal extends DocComponent SharingManager.Instance.open(this.props.DocumentView), icon: "users" }); - //moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" }); if (!Doc.UserDoc().noviceMode) { moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); moreItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" }); @@ -707,8 +664,7 @@ export class DocumentViewInternal extends DocComponent console.log(this.props.Document), icon: "hand-point-right" }); cm.addItem({ description: "Help...", noexpand: true, subitems: helpItems, icon: "question" }); - runInAction(() => { - if (!this.topMost) { - e?.stopPropagation(); // DocumentViews should stop propagation of this event - } - cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15); - !this.props.isSelected(true) && setTimeout(() => SelectionManager.SelectView(this.props.DocumentView, false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. - }); + if (!this.topMost) e?.stopPropagation(); // DocumentViews should stop propagation of this event + cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15); + !this.props.isSelected(true) && setTimeout(() => SelectionManager.SelectView(this.props.DocumentView, false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. } rootSelected = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; @@ -743,7 +695,7 @@ export class DocumentViewInternal extends DocComponent {this.layoutDoc.hideAllLinks ? (null) : this.allAnchors} - {this.hideLinkButton ? - (null) : - } - - ); + {this.hideLinkButton ? (null) : + } + ; } // used to decide whether a link anchor view should be created or not. @@ -780,10 +730,7 @@ export class DocumentViewInternal extends DocComponent this.props.PanelWidth() || 1; anchorPanelHeight = () => this.props.PanelHeight() || 1; anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { - switch (property.split(":")[0]) { - case StyleProp.LinkSource: return this.props.Document; // pass the LinkSource to the LinkAnchorBox - } - return this.props.styleProvider?.(doc, props, property + ":anchor"); + return property !== StyleProp.LinkSource ? this.props.styleProvider?.(doc, props, property + ":anchor") : this.props.Document; // pass the LinkSource to the LinkAnchorBox } @computed get directLinks() { TraceMobx(); return LinkManager.Instance.getAllDirectLinks(this.rootDoc); } @computed get allLinks() { TraceMobx(); return LinkManager.Instance.getAllRelatedLinks(this.rootDoc); } @@ -813,7 +760,7 @@ export class DocumentViewInternal extends DocComponent `} onClick={this.onClickFunc} layoutKey={this.finalLayoutKey} /> - ); - const titleView = (!showTitle ? (null) : + ; + const titleView = !showTitle ? (null) :
users.user.email === this.dataDoc.author)?.userColor || (this.rootDoc.type === DocumentType.RTF ? StrCast(Doc.SharingDoc().userColor) : "rgba(0,0,0,0.4)"), pointerEvents: this.onClickHandler || this.Document.ignoreClick ? "none" : undefined, }}> @@ -839,7 +786,7 @@ export class DocumentViewInternal extends DocComponent Field.toString((this.dataDoc || this.props.Document)[showTitle.split(";")[0]] as any as Field)} SetValue={undoBatch((value) => showTitle.includes("Date") ? true : (Doc.GetProto(this.dataDoc || this.props.Document)[showTitle] = value) ? true : true)} /> -
); + ; return this.props.hideTitle || (!showTitle && !showCaption) ? this.contents :
@@ -878,29 +825,21 @@ export class DocumentViewInternal extends DocComponent !SnappingManager.GetIsDragging() && Doc.BrushDoc(this.props.Document))} - onPointerLeave={action(e => { - let entered = false; - for (let child = document.elementFromPoint(e.nativeEvent.x, e.nativeEvent.y); !entered && child; child = child.parentElement) { - entered = entered || child === this.ContentDiv; - } - !entered && Doc.UnBrushDoc(this.props.Document); - })} + onPointerEnter={e => !SnappingManager.GetIsDragging() && Doc.BrushDoc(this.props.Document)} + onPointerLeave={e => hasDescendantTarget(e.nativeEvent.x, e.nativeEvent.y, this.ContentDiv) && Doc.UnBrushDoc(this.props.Document)} style={{ borderRadius: this.borderRounding, pointerEvents: this.pointerEvents, outline: highlighting && !this.borderRounding ? `${highlightColor} ${highlightStyle} ${highlightIndex}px` : "solid 0px", border: highlighting && this.borderRounding && highlightStyle === "dashed" ? `${highlightStyle} ${highlightColor} ${highlightIndex}px` : undefined, boxShadow, - }} - > + }}> {PresBox.EffectsProvider(this.layoutDoc, this.renderDoc) || this.renderDoc}
; } @@ -915,32 +854,23 @@ export class DocumentView extends React.Component { @observable LinkBeingCreated: Opt; // see DocumentLinksButton for explanation of how this works @observable public docView: DocumentViewInternal | undefined | null; + get Document() { return this.props.Document; } + get topMost() { return this.props.renderDepth === 0; } get rootDoc() { return this.docView?.rootDoc || this.Document; } get dataDoc() { return this.docView?.dataDoc || this.Document; } get finalLayoutKey() { return this.docView?.finalLayoutKey || "layout"; } get ContentDiv() { return this.docView?.ContentDiv; } get allLinks() { return this.docView?.allLinks || []; } get LayoutFieldKey() { return this.docView?.LayoutFieldKey || "layout"; } - toggleFollowLink = (location: Opt, zoom: boolean, setPushpin: boolean) => this.docView?.toggleFollowLink(location, zoom, setPushpin); - toggleNativeDimensions = () => this.docView?.toggleNativeDimensions(); - contentsActive = () => this.docView?.contentsActive(); - get Document() { return this.props.Document; } - get topMost() { return this.props.renderDepth === 0; } @computed get layoutDoc() { return Doc.Layout(this.Document, this.props.LayoutTemplate?.()); } - @computed get nativeWidth() { return returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions)); } @computed get nativeHeight() { return returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions) || 0); } @computed get nativeScaling() { - const nativeW = this.nativeWidth; - const nativeH = this.nativeHeight; - let scaling = 1; - if (nativeW && (this.layoutDoc?._fitWidth || this.props.PanelHeight() / nativeH > this.props.PanelWidth() / nativeW)) { - scaling = this.props.PanelWidth() / nativeW; // width-limited or fitWidth - } else if (nativeW && nativeH) { - scaling = this.props.PanelHeight() / nativeH; // height-limited + if (this.nativeWidth && (this.layoutDoc?._fitWidth || this.props.PanelHeight() / this.nativeHeight > this.props.PanelWidth() / this.nativeWidth)) { + return this.props.PanelWidth() / this.nativeWidth; // width-limited or fitWidth } - return scaling; + return this.nativeWidth && this.nativeHeight ? this.props.PanelHeight() / this.nativeHeight : 1; // height-limited or unscaled } @computed get panelWidth() { return this.nativeWidth ? this.nativeWidth * this.nativeScaling : this.props.PanelWidth(); } @@ -949,16 +879,17 @@ export class DocumentView extends React.Component { if (this.props.Document._fitWidth) { return Math.min(this.props.PanelHeight(), NumCast(this.props.Document.scrollHeight, this.props.PanelHeight())); } - else return Math.min(this.props.PanelHeight(), this.nativeHeight * this.nativeScaling); + return Math.min(this.props.PanelHeight(), this.nativeHeight * this.nativeScaling); } return this.props.PanelHeight(); } - @computed get Xshift() { return this.nativeWidth ? (this.props.PanelWidth() - this.nativeWidth * this.nativeScaling) / 2 : 0; } @computed get YShift() { return this.nativeWidth && this.nativeHeight && Math.abs(this.Xshift) < 0.001 ? (this.props.PanelHeight() - this.nativeHeight * this.nativeScaling) / 2 : 0; } @computed get centeringX() { return this.props.dontCenter?.includes("x") ? 0 : this.Xshift; } @computed get centeringY() { return this.props.Document._fitWidth || this.props.dontCenter?.includes("y") ? 0 : this.YShift; } + toggleNativeDimensions = () => this.docView && Doc.toggleNativeDimensions(this.layoutDoc, this.docView.ContentScale, this.props.PanelWidth(), this.props.PanelHeight()); + contentsActive = () => this.docView?.contentsActive(); getBounds = () => { if (!this.docView || !this.docView.ContentDiv || this.docView.props.renderDepth === 0 || this.docView.props.treeViewDoc || Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) { return undefined; diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts index 20e14a68d..e7cc89697 100644 --- a/src/pen-gestures/GestureUtils.ts +++ b/src/pen-gestures/GestureUtils.ts @@ -8,7 +8,6 @@ export namespace GestureUtils { readonly gesture: Gestures, readonly points: PointData[], readonly bounds: Rect, - readonly callbackFn?: Function, readonly text?: any ) { } } -- cgit v1.2.3-70-g09d2