diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/LinkManager.ts | 2 | ||||
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 4 | ||||
-rw-r--r-- | src/client/views/GlobalKeyHandler.ts | 16 | ||||
-rw-r--r-- | src/client/views/MainView.tsx | 3 | ||||
-rw-r--r-- | src/client/views/animationtimeline/Timeline.tsx | 1 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx | 37 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 10 | ||||
-rw-r--r-- | src/fields/util.ts | 1 |
8 files changed, 50 insertions, 24 deletions
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 694a7f3a7..269de08a1 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -67,7 +67,7 @@ export class LinkManager { const a2 = Cast(link.anchor2, Doc, null); const protomatch1 = Doc.AreProtosEqual(anchor, a1); const protomatch2 = Doc.AreProtosEqual(anchor, a2); - return ((a1?.title !== undefined && a2?.title !== undefined) || link.author === Doc.CurrentUserEmail) && (protomatch1 || protomatch2 || Doc.AreProtosEqual(link, anchor)); + return ((a1?.author !== undefined && a2?.author !== undefined) || link.author === Doc.CurrentUserEmail) && (protomatch1 || protomatch2 || Doc.AreProtosEqual(link, anchor)); }); return related; } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index fa7220e7d..066cfd95a 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -25,6 +25,7 @@ import React = require("react"); import e = require('express'); import { CurrentUserUtils } from '../util/CurrentUserUtils'; import { InkStrokeProperties } from './InkStrokeProperties'; +import { KeyManager } from './GlobalKeyHandler'; @observer export class DocumentDecorations extends React.Component<{}, { value: string }> { @@ -575,6 +576,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> "caret-up"; return <FontAwesomeIcon icon={button} className="documentView-minimizedIcon" />; } + render() { const darkScheme = CurrentUserUtils.ActiveDashboard?.darkScheme ? "dimgray" : undefined; const bounds = this.Bounds; @@ -625,7 +627,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> height: (bounds.b - bounds.y + this._resizeBorderWidth) + "px", left: bounds.x - this._resizeBorderWidth / 2, top: bounds.y - this._resizeBorderWidth / 2, - pointerEvents: this.Interacting ? "none" : "all", + pointerEvents: KeyManager.Instance.ShiftPressed || this.Interacting ? "none" : "all", zIndex: SelectionManager.SelectedDocuments().length > 1 ? 900 : 0, }} onPointerDown={this.onBackgroundDown} onContextMenu={e => { e.preventDefault(); e.stopPropagation(); }} > </div> diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index 0c05a1b69..9ca1dbf11 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -1,4 +1,4 @@ -import { action } from "mobx"; +import { action, observable } from "mobx"; import { DateField } from "../../fields/DateField"; import { Doc, DocListCast } from "../../fields/Doc"; import { Id } from "../../fields/FieldSymbols"; @@ -37,6 +37,7 @@ type KeyControlInfo = { export class KeyManager { public static Instance: KeyManager = new KeyManager(); private router = new Map<string, KeyHandler>(); + @observable ShiftPressed = false; constructor() { const isMac = navigator.platform.toLowerCase().indexOf("mac") >= 0; @@ -49,7 +50,12 @@ export class KeyManager { this.router.set("1000", this.shift); } - public handle = async (e: KeyboardEvent) => { + public unhandle = action((e: KeyboardEvent) => { + if (e.key.toLowerCase() === "shift") KeyManager.Instance.ShiftPressed = false; + }) + + public handle = action(async (e: KeyboardEvent) => { + if (e.key.toLowerCase() === "shift") KeyManager.Instance.ShiftPressed = true; const keyname = e.key && e.key.toLowerCase(); this.handleGreedy(keyname); @@ -69,7 +75,7 @@ export class KeyManager { control.stopPropagation && e.stopPropagation(); control.preventDefault && e.preventDefault(); - } + }) private handleGreedy = action((keyname: string) => { switch (keyname) { @@ -128,7 +134,7 @@ export class KeyManager { }; }); - private shift = async (keyname: string) => { + private shift = action(async (keyname: string) => { const stopPropagation = false; const preventDefault = false; @@ -143,7 +149,7 @@ export class KeyManager { stopPropagation: stopPropagation, preventDefault: preventDefault }; - } + }) private alt = action((keyname: string) => { const stopPropagation = true; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 5469c2358..5193c3c02 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -96,6 +96,8 @@ export class MainView extends React.Component { firstScriptTag.parentNode!.insertBefore(tag, firstScriptTag); window.removeEventListener("keydown", KeyManager.Instance.handle); window.addEventListener("keydown", KeyManager.Instance.handle); + window.removeEventListener("keyup", KeyManager.Instance.unhandle); + window.addEventListener("keyup", KeyManager.Instance.unhandle); window.addEventListener("paste", KeyManager.Instance.paste as any); document.addEventListener("dash", (e: any) => { // event used by chrome plugin to tell Dash which document to focus on const id = FormattedTextBox.GetDocFromUrl(e.detail); @@ -106,6 +108,7 @@ export class MainView extends React.Component { } componentWillUnMount() { + window.removeEventListener("keyup", KeyManager.Instance.unhandle); window.removeEventListener("keydown", KeyManager.Instance.handle); window.removeEventListener("pointerdown", this.globalPointerDown); window.removeEventListener("paste", KeyManager.Instance.paste as any); diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index e0935285f..093310755 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -484,7 +484,6 @@ export class Timeline extends React.Component<FieldViewProps> { render() { setTimeout(() => this.changeLengths(), 0); - trace(); // change visible and total width return ( <div style={{ visibility: "visible" }}> diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 011e10b88..8e01d9357 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -26,7 +26,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo this._anchorDisposer?.(); } @action - timeout = () => (Date.now() < this._start++ + 1000) && setTimeout(this.timeout, 25) + timeout = action(() => (Date.now() < this._start++ + 1000) && (this._timeout = setTimeout(this.timeout, 25))) componentDidMount() { this._anchorDisposer = reaction(() => [this.props.A.props.ScreenToLocalTransform(), this.props.B.props.ScreenToLocalTransform(), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document)], action(() => { @@ -113,7 +113,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo var el = el.parentNode; do { rect = el.getBoundingClientRect(); - if (top <= rect.bottom === false && getComputedStyle(el).overflow === "hidden") return rect.bottom; + if (top <= rect.right === false && getComputedStyle(el).overflow === "hidden") return rect.bottom; // Check if the element is out of view due to a container scrolling if ((top + height) <= rect.top && getComputedStyle(el).overflow === "hidden") return rect.top; el = el.parentNode; @@ -121,6 +121,20 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo // Check its within the document viewport return top; //top <= document.documentElement.clientHeight && getComputedStyle(document.documentElement).overflow === "hidden"; } + visibleX = (el: any) => { + let rect = el.getBoundingClientRect(); + const left = rect.left, width = rect.width; + var el = el.parentNode; + do { + rect = el.getBoundingClientRect(); + if (left <= rect.right === false && getComputedStyle(el).overflow === "hidden") return rect.right; + // Check if the element is out of view due to a container scrolling + if ((left + width) <= rect.left && getComputedStyle(el).overflow === "hidden") return rect.left; + el = el.parentNode; + } while (el !== document.body); + // Check its within the document viewport + return left; //top <= document.documentElement.clientHeight && getComputedStyle(document.documentElement).overflow === "hidden"; + } @computed.struct get renderData() { this._start; SnappingManager.GetIsDragging(); @@ -138,16 +152,18 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo const b = bdiv.getBoundingClientRect(); const atop = this.visibleY(adiv); const btop = this.visibleY(bdiv); - const apt = Utils.closestPtBetweenRectangles(a.left, atop, a.width, a.height, - b.left, btop, b.width, b.height, + const aleft = this.visibleX(adiv); + const bleft = this.visibleX(bdiv); + const apt = Utils.closestPtBetweenRectangles(aleft, atop, a.width, a.height, + bleft, btop, b.width, b.height, a.left + a.width / 2, a.top + a.height / 2); - const bpt = Utils.closestPtBetweenRectangles(b.left, btop, b.width, b.height, - a.left, atop, a.width, a.height, + const bpt = Utils.closestPtBetweenRectangles(bleft, btop, b.width, b.height, + aleft, atop, a.width, a.height, apt.point.x, apt.point.y); const pt1 = [apt.point.x, apt.point.y]; const pt2 = [bpt.point.x, bpt.point.y]; - const pt1vec = [pt1[0] - (a.left + a.width / 2), pt1[1] - (atop + a.height / 2)]; - const pt2vec = [pt2[0] - (b.left + b.width / 2), pt2[1] - (btop + b.height / 2)]; + const pt1vec = [pt1[0] - (aleft + a.width / 2), pt1[1] - (atop + a.height / 2)]; + const pt2vec = [pt2[0] - (bleft + b.width / 2), pt2[1] - (btop + b.height / 2)]; const pt1len = Math.sqrt((pt1vec[0] * pt1vec[0]) + (pt1vec[1] * pt1vec[1])); const pt2len = Math.sqrt((pt2vec[0] * pt2vec[0]) + (pt2vec[1] * pt2vec[1])); const ptlen = Math.sqrt((pt1[0] - pt2[0]) * (pt1[0] - pt2[0]) + (pt1[1] - pt2[1]) * (pt1[1] - pt2[1])) / 2; @@ -155,6 +171,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo const pt2norm = [pt2vec[0] / pt2len * ptlen, pt2vec[1] / pt2len * ptlen]; const aActive = this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document); const bActive = this.props.B.isSelected() || Doc.IsBrushed(this.props.B.props.Document); + if (aleft !== a.left || atop !== a.top || bleft !== b.left || btop !== b.top) return { a, b, pt1norm: [0, 0], pt2norm: [0, 0], aActive, bActive, textX: undefined, textY: undefined, pt1, pt2 }; const textX = (Math.min(pt1[0], pt2[0]) + Math.max(pt1[0], pt2[0])) / 2 + NumCast(this.props.LinkDocs[0].linkOffsetX); const textY = (pt1[1] + pt2[1]) / 2 + NumCast(this.props.LinkDocs[0].linkOffsetY); @@ -167,9 +184,9 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo return !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<> <path className="collectionfreeformlinkview-linkLine" style={{ opacity: this._opacity, strokeDasharray: "2 2" }} d={`M ${pt1[0]} ${pt1[1]} C ${pt1[0] + pt1norm[0]} ${pt1[1] + pt1norm[1]}, ${pt2[0] + pt2norm[0]} ${pt2[1] + pt2norm[1]}, ${pt2[0]} ${pt2[1]}`} /> - <text className="collectionfreeformlinkview-linkText" x={textX} y={textY} onPointerDown={this.pointerDown} > + {textX === undefined ? (null) : <text className="collectionfreeformlinkview-linkText" x={textX} y={textY} onPointerDown={this.pointerDown} > {StrCast(this.props.LinkDocs[0].description)} - </text> + </text>} </>); } }
\ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index ba762d01a..5f99f27b1 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -401,7 +401,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu const addTab = docView.addDocTab(doc, where); addTab && setTimeout(() => { const targDocView = DocumentManager.Instance.getFirstDocumentView(doc); - targDocView?.props.focus(doc, BoolCast(sourceDoc.followLinkZoom, true), undefined, hackToCallFinishAfterFocus); + targDocView?.props.focus(doc, BoolCast(sourceDoc.followLinkZoom, false), undefined, hackToCallFinishAfterFocus); }); // add the target and focus on it. return where !== "inPlace" || addTab; // return true to reset the initial focus&zoom (return false for 'inPlace' since resetting the initial focus&zoom will negate the zoom into the target) }; @@ -412,7 +412,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu docView.focus(sourceDoc, BoolCast(sourceDoc.followLinkZoom, true), 1, targetFocusAfterDocFocus); } }; - await DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, createViewFunc, BoolCast(sourceDoc.followLinkZoom, true), docView.ContainingCollectionDoc, batch.end, altKey ? true : undefined); + await DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, createViewFunc, BoolCast(sourceDoc.followLinkZoom, false), docView.ContainingCollectionDoc, batch.end, altKey ? true : undefined); } handle1PointerDown = (e: React.TouchEvent, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>) => { @@ -987,9 +987,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu anchorPanelWidth = () => this.props.PanelWidth() || 1; anchorPanelHeight = () => this.props.PanelHeight() || 1; - @computed.struct get directLinks() { return LinkManager.Instance.getAllDirectLinks(this.rootDoc); } - @computed.struct get allLinks() { return DocListCast(this.Document.links); } - @computed.struct get allAnchors() { + @computed get directLinks() { TraceMobx(); return LinkManager.Instance.getAllDirectLinks(this.rootDoc); } + @computed get allLinks() { TraceMobx(); return DocListCast(this.Document.links); } + @computed get allAnchors() { TraceMobx(); if (this.props.LayoutTemplateString?.includes("LinkAnchorBox")) return null; if ((this.props.treeViewDoc && this.props.LayoutTemplateString) || // render nothing for: tree view anchor dots diff --git a/src/fields/util.ts b/src/fields/util.ts index 989166bf8..f0ff2dad4 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -11,7 +11,6 @@ import { ComputedField } from "./ScriptField"; import { ScriptCast, StrCast } from "./Types"; import { returnZero } from "../Utils"; import CursorField from "./CursorField"; -import { List } from "@material-ui/core"; function _readOnlySetter(): never { |