From 749873972fba8ed8d5b34b73b43947d6356b882e Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 22 Oct 2020 22:23:39 -0400 Subject: added more caching for linkManager queries. --- src/client/util/LinkManager.ts | 106 +++++++++++------------------------------ 1 file changed, 29 insertions(+), 77 deletions(-) (limited to 'src/client/util/LinkManager.ts') diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 1ba6cff6d..c3ab7c6e7 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -25,94 +25,52 @@ export class LinkManager { public static currentLink: Opt; - public static get Instance(): LinkManager { - return this._instance || (this._instance = new this()); - } - - private constructor() { - } - + public static get Instance(): LinkManager { return this._instance || (this._instance = new this()); } - public getAllLinks(): Doc[] { - const lset = new Set(DocListCast(Doc.LinkDBDoc().data)); - SharingManager.Instance.users.forEach(user => { - DocListCast(user.linkDatabase?.data).map(doc => { - lset.add(doc); - }); - }); - return Array.from(lset); - } + public addLink(linkDoc: Doc) { return Doc.AddDocToList(Doc.LinkDBDoc(), "data", linkDoc); } - public addLink(linkDoc: Doc): boolean { - return Doc.AddDocToList(Doc.LinkDBDoc(), "data", linkDoc); - } + public deleteLink(linkDoc: Doc) { return Doc.RemoveDocFromList(Doc.LinkDBDoc(), "data", linkDoc); } - public deleteLink(linkDoc: Doc): boolean { - return Doc.RemoveDocFromList(Doc.LinkDBDoc(), "data", linkDoc); - } + public deleteAllLinksOnAnchor(anchor: Doc) { LinkManager.Instance.getAllRelatedLinks(anchor).forEach(linkDoc => LinkManager.Instance.deleteLink(linkDoc)); } - // finds all links that contain the given anchor - public getAllDirectLinks(anchor: Doc): Doc[] { - const related = LinkManager.Instance.getAllLinks().filter(link => link).filter(link => { - const a1 = Cast(link.anchor1, Doc, null); - const a2 = Cast(link.anchor2, Doc, null); - const protomatch1 = Doc.AreProtosEqual(anchor, a1); - const protomatch2 = Doc.AreProtosEqual(anchor, a2); - return ((a1?.author !== undefined && a2?.author !== undefined) || link.author === Doc.CurrentUserEmail) && (protomatch1 || protomatch2 || Doc.AreProtosEqual(link, anchor)); - }); - return related; - } + public getAllRelatedLinks(anchor: Doc) { return this.relatedLinker(anchor); } // finds all links that contain the given anchor - relatedLinker = computedFn(function realtedLinker(this: any, anchor: Doc) { - const related = LinkManager.Instance.getAllDirectLinks(anchor); - DocListCast(anchor[Doc.LayoutFieldKey(anchor) + "-annotations"]).map(anno => { - related.push(...LinkManager.Instance.getAllRelatedLinks(anno)); - }); - return related; - }.bind(this), true); + public getAllDirectLinks(anchor: Doc): Doc[] { return this.directLinker(anchor); } // finds all links that contain the given anchor - // finds all links that contain the given anchor - public getAllRelatedLinks(anchor: Doc): Doc[] { - return this.relatedLinker(anchor); - } + public getAllLinks(): Doc[] { return this.allLinks(); } - public deleteAllLinksOnAnchor(anchor: Doc) { - const related = LinkManager.Instance.getAllRelatedLinks(anchor); - related.forEach(linkDoc => LinkManager.Instance.deleteLink(linkDoc)); - } + allLinks = computedFn(function allLinks(this: any) { + const lset = new Set(DocListCast(Doc.LinkDBDoc().data)); + SharingManager.Instance.users.forEach(user => DocListCast(user.linkDatabase?.data).map(doc => lset.add(doc))); + return Array.from(lset); + }, true); - // gets the groups associates with an anchor in a link - public getAnchorGroups(linkDoc: Doc, anchor?: Doc): Array { - if (Doc.AreProtosEqual(anchor, Cast(linkDoc.anchor1, Doc, null))) { - return DocListCast(linkDoc.anchor1Groups); - } else { - return DocListCast(linkDoc.anchor2Groups); - } - } - public addGroupToAnchor(linkDoc: Doc, anchor: Doc, groupDoc: Doc, replace: boolean = false) { - Doc.GetProto(linkDoc).linkRelationship = groupDoc.linkRelationship; - } + directLinker = computedFn(function directLinker(this: any, anchor: Doc) { + return LinkManager.Instance.getAllLinks().filter(link => { + const a1 = Cast(link?.anchor1, Doc, null); + const a2 = Cast(link?.anchor2, Doc, null); + return link && ((a1?.author !== undefined && a2?.author !== undefined) || link.author === Doc.CurrentUserEmail) && (Doc.AreProtosEqual(anchor, a1) || Doc.AreProtosEqual(anchor, a2) || Doc.AreProtosEqual(link, anchor)); + }); + }, true); - // removes group doc of given group type only from given anchor on given link - public removeGroupFromAnchor(linkDoc: Doc, anchor: Doc, groupType: string) { - Doc.GetProto(linkDoc).linkRelationship = "-ungrouped-"; - } + relatedLinker = computedFn(function relatedLinker(this: any, anchor: Doc) { + const related = LinkManager.Instance.directLinker(anchor); + DocListCast(anchor[Doc.LayoutFieldKey(anchor) + "-annotations"]).map(anno => related.push(...LinkManager.Instance.getAllRelatedLinks(anno))); + return related; + }, true); // returns map of group type to anchor's links in that group type public getRelatedGroupedLinks(anchor: Doc): Map> { - const related = this.getAllRelatedLinks(anchor); const anchorGroups = new Map>(); - related.forEach(link => { + this.getAllRelatedLinks(anchor).forEach(link => { if (!link.linkRelationship || link?.linkRelationship !== "-ungrouped-") { const group = anchorGroups.get(StrCast(link.linkRelationship)); anchorGroups.set(StrCast(link.linkRelationship), group ? [...group, link] : [link]); - } else { // if link is in no groups then put it in default group const group = anchorGroups.get("*"); anchorGroups.set("*", group ? [...group, link] : [link]); } - }); return anchorGroups; } @@ -120,21 +78,15 @@ export class LinkManager { // returns a list of all metadata docs associated with the given group type public getAllMetadataDocsInGroup(groupType: string): Array { const md: Doc[] = []; - const allLinks = LinkManager.Instance.getAllLinks(); - allLinks.forEach(linkDoc => { - if (StrCast(linkDoc.linkRelationship).toUpperCase() === groupType.toUpperCase()) { md.push(linkDoc); } - }); + LinkManager.Instance.getAllLinks().forEach(linkDoc => StrCast(linkDoc.linkRelationship).toUpperCase() === groupType.toUpperCase() && md.push(linkDoc)); return md; } // checks if a link with the given anchors exists public doesLinkExist(anchor1: Doc, anchor2: Doc): boolean { - const allLinks = LinkManager.Instance.getAllLinks(); - const index = allLinks.findIndex(linkDoc => { - return (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor1) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor2)) || - (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor2) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor1)); - }); - return index !== -1; + return -1 !== LinkManager.Instance.getAllLinks().findIndex(linkDoc => + (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor1) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor2)) || + (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor2) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor1))); } // finds the opposite anchor of a given anchor in a link -- cgit v1.2.3-70-g09d2 From f23e2f2bcb6ab7fb1895a87a34f8eafcbab90a8d Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 3 Nov 2020 21:40:53 -0500 Subject: fixed LinkManager to cache links correctly. fixes issue with linkButton not showing the correct number. --- src/client/util/LinkManager.ts | 28 +++---- src/client/views/nodes/DocumentLinksButton.tsx | 109 ++++++++++--------------- src/client/views/nodes/DocumentView.tsx | 2 +- 3 files changed, 57 insertions(+), 82 deletions(-) (limited to 'src/client/util/LinkManager.ts') diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index c3ab7c6e7..3a0c0e3eb 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -22,47 +22,41 @@ import { computedFn } from "mobx-utils"; export class LinkManager { private static _instance: LinkManager; - public static currentLink: Opt; - public static get Instance(): LinkManager { return this._instance || (this._instance = new this()); } public addLink(linkDoc: Doc) { return Doc.AddDocToList(Doc.LinkDBDoc(), "data", linkDoc); } - public deleteLink(linkDoc: Doc) { return Doc.RemoveDocFromList(Doc.LinkDBDoc(), "data", linkDoc); } - - public deleteAllLinksOnAnchor(anchor: Doc) { LinkManager.Instance.getAllRelatedLinks(anchor).forEach(linkDoc => LinkManager.Instance.deleteLink(linkDoc)); } + public deleteAllLinksOnAnchor(anchor: Doc) { LinkManager.Instance.relatedLinker(anchor).forEach(linkDoc => LinkManager.Instance.deleteLink(linkDoc)); } public getAllRelatedLinks(anchor: Doc) { return this.relatedLinker(anchor); } // finds all links that contain the given anchor - public getAllDirectLinks(anchor: Doc): Doc[] { return this.directLinker(anchor); } // finds all links that contain the given anchor - public getAllLinks(): Doc[] { return this.allLinks(); } - allLinks = computedFn(function allLinks(this: any) { + allLinks = computedFn(function allLinks(this: any): Doc[] { const lset = new Set(DocListCast(Doc.LinkDBDoc().data)); SharingManager.Instance.users.forEach(user => DocListCast(user.linkDatabase?.data).map(doc => lset.add(doc))); return Array.from(lset); }, true); - directLinker = computedFn(function directLinker(this: any, anchor: Doc) { - return LinkManager.Instance.getAllLinks().filter(link => { + directLinker = computedFn(function directLinker(this: any, anchor: Doc): Doc[] { + return LinkManager.Instance.allLinks().filter(link => { const a1 = Cast(link?.anchor1, Doc, null); const a2 = Cast(link?.anchor2, Doc, null); return link && ((a1?.author !== undefined && a2?.author !== undefined) || link.author === Doc.CurrentUserEmail) && (Doc.AreProtosEqual(anchor, a1) || Doc.AreProtosEqual(anchor, a2) || Doc.AreProtosEqual(link, anchor)); }); }, true); - relatedLinker = computedFn(function relatedLinker(this: any, anchor: Doc) { - const related = LinkManager.Instance.directLinker(anchor); - DocListCast(anchor[Doc.LayoutFieldKey(anchor) + "-annotations"]).map(anno => related.push(...LinkManager.Instance.getAllRelatedLinks(anno))); - return related; + relatedLinker = computedFn(function relatedLinker(this: any, anchor: Doc): Doc[] { + return DocListCast(anchor[Doc.LayoutFieldKey(anchor) + "-annotations"]).reduce((list, anno) => + [...list, ...LinkManager.Instance.relatedLinker(anno)], + LinkManager.Instance.directLinker(anchor).slice()); }, true); // returns map of group type to anchor's links in that group type public getRelatedGroupedLinks(anchor: Doc): Map> { const anchorGroups = new Map>(); - this.getAllRelatedLinks(anchor).forEach(link => { + this.relatedLinker(anchor).forEach(link => { if (!link.linkRelationship || link?.linkRelationship !== "-ungrouped-") { const group = anchorGroups.get(StrCast(link.linkRelationship)); anchorGroups.set(StrCast(link.linkRelationship), group ? [...group, link] : [link]); @@ -78,13 +72,13 @@ export class LinkManager { // returns a list of all metadata docs associated with the given group type public getAllMetadataDocsInGroup(groupType: string): Array { const md: Doc[] = []; - LinkManager.Instance.getAllLinks().forEach(linkDoc => StrCast(linkDoc.linkRelationship).toUpperCase() === groupType.toUpperCase() && md.push(linkDoc)); + LinkManager.Instance.allLinks().forEach(linkDoc => StrCast(linkDoc.linkRelationship).toUpperCase() === groupType.toUpperCase() && md.push(linkDoc)); return md; } // checks if a link with the given anchors exists public doesLinkExist(anchor1: Doc, anchor2: Doc): boolean { - return -1 !== LinkManager.Instance.getAllLinks().findIndex(linkDoc => + return -1 !== LinkManager.Instance.allLinks().findIndex(linkDoc => (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor1) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor2)) || (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor2) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor1))); } diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index a167f2a23..95c007175 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -3,7 +3,6 @@ import { Tooltip } from "@material-ui/core"; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocListCast, Opt } from "../../../fields/Doc"; -import { DocumentType } from "../../documents/DocumentTypes"; import { emptyFunction, setupMoveUpEvents, returnFalse, Utils, emptyPath } from "../../../Utils"; import { TraceMobx } from "../../../fields/util"; import { DocUtils, Docs } from "../../documents/Documents"; @@ -39,6 +38,7 @@ export class DocumentLinksButton extends React.Component; public static invisibleWebRef = React.createRef(); @@ -209,94 +209,75 @@ export class DocumentLinksButton extends React.Component(this.props.links)), this.props.View.props.docFilters(), []); - - const menuTitle = this.props.StartLink ? "Drag or tap to start link" : "Tap to complete link"; - const buttonTitle = "Tap to view links"; - const title = this.props.InMenu ? menuTitle : buttonTitle; - - - const startLink = ; - - const endLink = ; + @computed get filteredLinks() { + return DocUtils.FilterDocs(Array.from(new Set(this.props.links)), this.props.View.props.docFilters(), []); + } - const link = ; + @computed get linkButtonInner() { + const btnDim = this.props.InMenu ? "20px" : "30px"; + const link = ; - const linkButton =
-
+
LinkDocPreview.LinkInfo = undefined)} - // onPointerEnter={action(e => links.length && (LinkDocPreview.LinkInfo = { - // addDocTab: this.props.View.props.addDocTab, - // linkSrc: this.props.View.props.Document, - // linkDoc: links[0], - // Location: [e.clientX, e.clientY + 20] - // }))} - > - - {/* {this.props.InMenu ? this.props.StartLink ? : - : links.length} */} - - {this.props.InMenu ? this.props.StartLink ? : - link : Array.from(links).length} - + style={{ + backgroundColor: this.props.InMenu ? "" : "#add8e6", + color: this.props.InMenu ? "white" : "black", + width: btnDim, + height: btnDim, + }} > + {this.props.InMenu ? + this.props.StartLink ? + + : link + : Array.from(this.filteredLinks).length}
{this.props.InMenu && !this.props.StartLink && DocumentLinksButton.StartLink !== this.props.View.props.Document ?
DocumentLinksButton.StartLink ? DocumentLinksButton.finishLinkClick(e.clientX, e.clientY, DocumentLinksButton.StartLink, this.props.View.props.Document, true, this.props.View) : emptyFunction} /> : (null) + onPointerDown={DocumentLinksButton.StartLink && this.completeLink} + onClick={e => DocumentLinksButton.StartLink && DocumentLinksButton.finishLinkClick(e.clientX, e.clientY, DocumentLinksButton.StartLink, this.props.View.props.Document, true, this.props.View)} /> + : (null) } - { - DocumentLinksButton.StartLink === this.props.View.props.Document && this.props.InMenu && this.props.StartLink ?
: (null) + {DocumentLinksButton.StartLink === this.props.View.props.Document && this.props.InMenu && this.props.StartLink ? +
+ : (null) }
; + } + + @computed get linkButton() { + TraceMobx(); + + const menuTitle = this.props.StartLink ? "Drag or tap to start link" : "Tap to complete link"; + const buttonTitle = "Tap to view links"; + const title = this.props.InMenu ? menuTitle : buttonTitle; - return (!Array.from(links).length) && !this.props.AlwaysOn ? (null) : + return !Array.from(this.filteredLinks).length && !this.props.AlwaysOn ? (null) : this.props.InMenu && (DocumentLinksButton.StartLink || this.props.StartLink) ?
{title}
}> - {linkButton} -
: !!!DocumentLinksButton.EditLink && !this.props.InMenu ? + {this.linkButtonInner} + + : + !DocumentLinksButton.EditLink && !this.props.InMenu ?
{title}
}> - {linkButton} -
: - linkButton; + {this.linkButtonInner} + + : this.linkButtonInner; } render() { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index f6a147c50..3ebaad0a3 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -990,7 +990,7 @@ export class DocumentView extends DocComponent(Docu anchorPanelHeight = () => this.props.PanelHeight() || 1; @computed get directLinks() { TraceMobx(); return LinkManager.Instance.getAllDirectLinks(this.rootDoc); } - @computed get allLinks() { TraceMobx(); return DocListCast(this.Document.links); } + @computed get allLinks() { TraceMobx(); return LinkManager.Instance.getAllRelatedLinks(this.rootDoc); } @computed get allAnchors() { TraceMobx(); if (this.props.LayoutTemplateString?.includes("LinkAnchorBox")) return null; -- cgit v1.2.3-70-g09d2 From 83d3756537cfcd8a2248c4b8a2a6f75f77154602 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 9 Nov 2020 21:40:59 -0500 Subject: fixed autoHeight for formattedTextSidebars when the text document has been scaled. cleaned up link groups. fixed pushpins that don't focus on target (e.g., a si m ple pushpin on a PDF). --- src/client/util/LinkManager.ts | 9 +---- .../views/collections/CollectionStackingView.tsx | 10 +++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 3 +- src/client/views/linking/LinkMenu.tsx | 29 ++++++--------- src/client/views/linking/LinkMenuGroup.tsx | 43 +++------------------- src/client/views/nodes/LinkDocPreview.tsx | 17 ++++----- .../views/nodes/formattedText/FormattedTextBox.tsx | 20 +++++----- 7 files changed, 42 insertions(+), 89 deletions(-) (limited to 'src/client/util/LinkManager.ts') diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 3a0c0e3eb..802b8ae7b 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -35,7 +35,7 @@ export class LinkManager { allLinks = computedFn(function allLinks(this: any): Doc[] { const lset = new Set(DocListCast(Doc.LinkDBDoc().data)); - SharingManager.Instance.users.forEach(user => DocListCast(user.linkDatabase?.data).map(doc => lset.add(doc))); + SharingManager.Instance.users.forEach(user => DocListCast(user.linkDatabase?.data).forEach(doc => lset.add(doc))); return Array.from(lset); }, true); @@ -69,13 +69,6 @@ export class LinkManager { return anchorGroups; } - // returns a list of all metadata docs associated with the given group type - public getAllMetadataDocsInGroup(groupType: string): Array { - const md: Doc[] = []; - LinkManager.Instance.allLinks().forEach(linkDoc => StrCast(linkDoc.linkRelationship).toUpperCase() === groupType.toUpperCase() && md.push(linkDoc)); - return md; - } - // checks if a link with the given anchors exists public doesLinkExist(anchor1: Doc, anchor2: Doc): boolean { return -1 !== LinkManager.Instance.allLinks().findIndex(linkDoc => diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 62f733058..97eacaeab 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -352,8 +352,12 @@ export class CollectionStackingView extends CollectionSubView { if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { - const height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", ""))))); - Doc.Layout(doc)._height = Math.max(height, NumCast(doc[this.props.fieldKey + "-height"])); + const height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), Math.max(...this.refList.map(r => NumCast(Doc.Layout(doc)._viewScale, 1) * Number(getComputedStyle(r).height.replace("px", ""))))); + if (this.props.annotationsKey) { + doc[this.props.annotationsKey + "-height"] = height; + } else { + Doc.Layout(doc)._height = height * NumCast(Doc.Layout(doc)._viewScale, 1); + } } })); this.observer.observe(ref); @@ -406,7 +410,7 @@ export class CollectionStackingView extends CollectionSubView { if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { const height = this.refList.reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0); - Doc.Layout(doc)._height = Math.max(height, NumCast(doc[this.props.fieldKey + "-height"])); + Doc.Layout(doc)._height = Math.max(height * NumCast(doc[this.props.fieldKey + "-height"]), NumCast(doc[this.props.fieldKey + "-height"])); } })); this.observer.observe(ref); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 4541716f3..21e653e02 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -926,8 +926,7 @@ export class CollectionFreeFormView extends CollectionSubView { } renderAllGroups = (groups: Map>): Array => { - const linkItems: Array = []; - groups.forEach((group, groupType) => { - linkItems.push( - this._editingLink = linkDoc)} - addDocTab={this.props.addDocTab} /> - ); - }); - - // if source doc has no links push message - if (linkItems.length === 0) linkItems.push(

No links have been created yet. Drag the linking button onto another document to create a link.

); - - return linkItems; + const linkItems = Array.from(groups.entries()).map(group => + this._editingLink = linkDoc)} + addDocTab={this.props.addDocTab} />); + + return linkItems.length ? linkItems : [

No links have been created yet. Drag the linking button onto another document to create a link.

]; } @computed diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx index e76227ccf..e53655fd3 100644 --- a/src/client/views/linking/LinkMenuGroup.tsx +++ b/src/client/views/linking/LinkMenuGroup.tsx @@ -1,17 +1,12 @@ -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action } from "mobx"; import { observer } from "mobx-react"; import { Doc } from "../../../fields/Doc"; import { Id } from "../../../fields/FieldSymbols"; -import { SchemaHeaderField } from "../../../fields/SchemaHeaderField"; -import { Docs } from "../../documents/Documents"; -import { DragManager, SetupDrag } from "../../util/DragManager"; +import { Cast } from "../../../fields/Types"; import { LinkManager } from "../../util/LinkManager"; import { DocumentView } from "../nodes/DocumentView"; import './LinkMenu.scss'; -import { LinkMenuItem, StartLinkTargetsDrag } from "./LinkMenuItem"; +import { LinkMenuItem } from "./LinkMenuItem"; import React = require("react"); -import { Cast } from "../../../fields/Types"; interface LinkMenuGroupProps { sourceDoc: Doc; @@ -26,34 +21,8 @@ interface LinkMenuGroupProps { export class LinkMenuGroup extends React.Component { private _drag = React.createRef(); - private _table = React.createRef(); private _menuRef = React.createRef(); - onLinkButtonDown = (e: React.PointerEvent): void => { - e.stopPropagation(); - document.removeEventListener("pointermove", this.onLinkButtonMoved); - document.addEventListener("pointermove", this.onLinkButtonMoved); - document.removeEventListener("pointerup", this.onLinkButtonUp); - document.addEventListener("pointerup", this.onLinkButtonUp); - } - - onLinkButtonUp = (e: PointerEvent): void => { - document.removeEventListener("pointermove", this.onLinkButtonMoved); - document.removeEventListener("pointerup", this.onLinkButtonUp); - e.stopPropagation(); - } - - onLinkButtonMoved = async (e: PointerEvent) => { - if (this._drag.current && (e.movementX > 1 || e.movementY > 1)) { - document.removeEventListener("pointermove", this.onLinkButtonMoved); - document.removeEventListener("pointerup", this.onLinkButtonUp); - - const targets = this.props.group.map(l => LinkManager.getOppositeAnchor(l, this.props.sourceDoc)).filter(d => d) as Doc[]; - StartLinkTargetsDrag(this._drag.current, this.props.docView, e.x, e.y, this.props.sourceDoc, targets); - } - e.stopPropagation(); - } - render() { const set = new Set(this.props.group); const groupItems = Array.from(set.keys()).map(linkDoc => { @@ -75,11 +44,9 @@ export class LinkMenuGroup extends React.Component { return (
- {/*
-

{this.props.groupType}:

- {this.props.groupType === "*" || this.props.groupType === "" ? <> : this.viewGroupAsTable(this.props.groupType)} -
*/} +
+

{this.props.groupType}:

+
{groupItems} diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index 867be9735..d47942bd9 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -77,19 +77,16 @@ export class LinkDocPreview extends React.Component { this.props.addDocTab(Docs.Create.WebDocument(this.props.href, { _fitWidth: true, title: this.props.href, _width: 200, _height: 400, useCors: true }), "add:right"); } } - width = () => Math.min(225, NumCast(this._targetDoc?.[WidthSym](), 225)) - 16; - height = () => Math.min(225, NumCast(this._targetDoc?.[HeightSym](), 225)) - 16; + width = () => Math.min(225, NumCast(this._targetDoc?.[WidthSym](), 225)); + height = () => Math.min(225, NumCast(this._targetDoc?.[HeightSym](), 225)); @computed get targetDocView() { return !this._targetDoc ? -
+
{this._toolTipText}
-
: - +
+ : { ContainingCollectionDoc={undefined} ContainingCollectionView={undefined} renderDepth={-1} - PanelWidth={this.width} //Math.min(350, NumCast(target._width, 350))} - PanelHeight={this.height} //Math.min(250, NumCast(target._height, 250))} + PanelWidth={this.width} + PanelHeight={this.height} focus={emptyFunction} whenActiveChanged={returnFalse} bringToFront={returnFalse} diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index bc9e8e99d..fe38939c5 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -812,6 +812,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } componentDidMount() { this._cachedLinks = DocListCast(this.Document.links); + this._disposers.sidebarheight = reaction( + () => ({ annoHeight: NumCast(this.rootDoc[this.annotationKey + "-height"]), textHeight: NumCast(this.rootDoc[this.fieldKey + "-height"]) }), + ({ annoHeight, textHeight }) => { + this.layoutDoc._autoHeight && (this.rootDoc._height = Math.max(annoHeight, textHeight)); + }); this._disposers.links = reaction(() => DocListCast(this.Document.links), // if a link is deleted, then remove all hyperlinks that reference it from the text's marks newLinks => { this._cachedLinks.forEach(l => !newLinks.includes(l) && this.RemoveLinkFromDoc(l)); @@ -1540,18 +1545,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp }, 10); } else { try { - const boxHeight = Number(getComputedStyle(this._boxRef.current!).height.replace("px", "")); + const boxHeight = Number(getComputedStyle(this._boxRef.current!).height.replace("px", "")) * NumCast(this.Document._viewScale, 1); const outer = this.rootDoc[HeightSym]() - boxHeight - (this.props.ChromeHeight ? this.props.ChromeHeight() : 0); - const finalHeight = newHeight + Math.max(0, outer); - const maxsidebar = !this.sidebarWidth() ? 0 : Array.from(this._boxRef.current!.getElementsByClassName("collectionStackingViewFieldColumn")).reduce((prev, ele) => Math.max(prev, Number(getComputedStyle(ele).height.replace("px", ""))), 0); - if (this.rootDoc._height !== finalHeight && finalHeight > maxsidebar) { - this.rootDoc._height = finalHeight; - this.layoutDoc._nativeHeight = nh ? scrollHeight : undefined; - } - this.rootDoc[this.fieldKey + "-height"] = finalHeight; + this.rootDoc[this.fieldKey + "-height"] = newHeight + Math.max(0, outer); } catch (e) { console.log("Error in tryUpdateHeight"); } } - } else this.rootDoc[this.fieldKey + "-height"] = 0; + } //else this.rootDoc[this.fieldKey + "-height"] = 0; } @computed get audioHandle() { @@ -1609,7 +1608,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); } sidebarWidth = () => Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth(); - sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()) / this.props.ContentScaling(), 0); + sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()) / this.props.ContentScaling(), 0).scale(1 / NumCast(this.layoutDoc._viewScale, 1)); @computed get sidebarColor() { return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "#e4e4e4")); } render() { TraceMobx(); @@ -1631,6 +1630,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp transformOrigin: "top left", width: `${100 / scale}%`, height: `calc(${100 / scale}% - ${this.props.ChromeHeight?.() || 0}px)`, + overflowY: this.layoutDoc._autoHeight ? "hidden" : undefined, ...this.styleFromLayoutString(scale) // this converts any expressions in the format string to style props. e.g., }}>