From 646175b9870fb535648c8a9473c245bac57474b3 Mon Sep 17 00:00:00 2001 From: dinhanhtruong <70963346+dinhanhtruong@users.noreply.github.com> Date: Sat, 28 Aug 2021 16:58:02 -0400 Subject: added variable link weights based on relationship importance Link lines are thicker for links belonging to more important relationships. Thickness varies linearly from 3px to 12px. Removed dashed linked lines. --- src/client/views/linking/LinkEditor.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/client/views/linking/LinkEditor.tsx') diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx index fba95cad2..f326e1440 100644 --- a/src/client/views/linking/LinkEditor.tsx +++ b/src/client/views/linking/LinkEditor.tsx @@ -2,7 +2,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Tooltip } from "@material-ui/core"; import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; -import { Doc, StrListCast } from "../../../fields/Doc"; +import { Doc, NumListCast, StrListCast } from "../../../fields/Doc"; import { DateCast, StrCast } from "../../../fields/Types"; import { LinkManager } from "../../util/LinkManager"; import { undoBatch } from "../../util/UndoManager"; @@ -43,12 +43,18 @@ export class LinkEditor extends React.Component { if (LinkManager.currentLink) { LinkManager.currentLink.linkRelationship = value; const linkRelationshipList = StrListCast(Doc.UserDoc().linkRelationshipList); + const linkRelationshipSizes = NumListCast(Doc.UserDoc().linkRelationshipSizes); const linkColorList = StrListCast(Doc.UserDoc().linkColorList); + // if the relationship does not exist in the list, add it and a corresponding unique randomly generated color if (linkRelationshipList && !linkRelationshipList.includes(value)) { linkRelationshipList.push(value); + linkRelationshipSizes.push(1); const randColor = "rgb(" + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + ")"; linkColorList.push(randColor) + } else { + //increment relationship size if rel already exists + linkRelationshipSizes[linkRelationshipList.indexOf(value)] = linkRelationshipSizes[linkRelationshipList.indexOf(value)] + 1; } this.relationshipButtonColor = "rgb(62, 133, 55)"; setTimeout(action(() => this.relationshipButtonColor = ""), 750); -- cgit v1.2.3-70-g09d2 From 2df1a0c0cc11c0dbcebf2a53e804cf8ac28db346 Mon Sep 17 00:00:00 2001 From: dinhanhtruong <70963346+dinhanhtruong@users.noreply.github.com> Date: Sun, 29 Aug 2021 13:47:03 -0400 Subject: fixed link counter when setting new relationships num of links per relationship should now update correctly when link relationships are set to new values --- src/client/views/linking/LinkEditor.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/client/views/linking/LinkEditor.tsx') diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx index f326e1440..ab8ce3da6 100644 --- a/src/client/views/linking/LinkEditor.tsx +++ b/src/client/views/linking/LinkEditor.tsx @@ -41,6 +41,7 @@ export class LinkEditor extends React.Component { @undoBatch setRelationshipValue = action((value: string) => { if (LinkManager.currentLink) { + const prevRelationship = LinkManager.currentLink.linkRelationship as string; LinkManager.currentLink.linkRelationship = value; const linkRelationshipList = StrListCast(Doc.UserDoc().linkRelationshipList); const linkRelationshipSizes = NumListCast(Doc.UserDoc().linkRelationshipSizes); @@ -52,9 +53,15 @@ export class LinkEditor extends React.Component { linkRelationshipSizes.push(1); const randColor = "rgb(" + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + ")"; linkColorList.push(randColor) - } else { - //increment relationship size if rel already exists + // if the relationship is already in the list AND the new rel is different from the prev rel, update the rel sizes + } else if (linkRelationshipList && value != prevRelationship) { + //increment size of new relationship size linkRelationshipSizes[linkRelationshipList.indexOf(value)] = linkRelationshipSizes[linkRelationshipList.indexOf(value)] + 1; + //decrement the size of the previous relationship if it already exists (i.e. not default 'link' relationship upon link creation) + if (linkRelationshipList.includes(prevRelationship)) { + linkRelationshipSizes[linkRelationshipList.indexOf(prevRelationship)] = linkRelationshipSizes[linkRelationshipList.indexOf(prevRelationship)] - 1; + } + } this.relationshipButtonColor = "rgb(62, 133, 55)"; setTimeout(action(() => this.relationshipButtonColor = ""), 750); @@ -146,6 +153,7 @@ export class LinkEditor extends React.Component { style={{ width: "100%" }} id="input" value={this.relationship} + autoComplete={"off"} placeholder={"Enter link relationship"} onKeyDown={this.onRelationshipKey} onChange={this.handleRelationshipChange} @@ -174,6 +182,7 @@ export class LinkEditor extends React.Component {
Date: Fri, 17 Sep 2021 14:07:09 -0400 Subject: added 'unset' docFilters. changed link doc views to use comparison box with title/caption. fixed linkEditor to write to data doc. generalized comparisonBox rendering to use parameterized fields. fixed pdf/web to honor pointerEvents none prop and fixed textAnnotations to get rendered once as an Annotation. moved filterIcon stuff into DocumentView --- src/Utils.ts | 4 +++- src/client/DocServer.ts | 2 ++ src/client/documents/Documents.ts | 17 +++++++++++------ src/client/views/collections/CollectionView.tsx | 12 ------------ .../collectionFreeForm/CollectionFreeFormLinkView.tsx | 6 +++--- src/client/views/linking/LinkEditor.tsx | 11 ++++++----- src/client/views/nodes/ComparisonBox.tsx | 8 +++++--- src/client/views/nodes/DocumentView.tsx | 19 +++++++++++++++++-- src/client/views/nodes/LinkBox.tsx | 19 ++++++------------- src/client/views/nodes/LinkDescriptionPopup.tsx | 7 ++++--- src/client/views/nodes/PDFBox.tsx | 9 ++++----- src/client/views/nodes/WebBox.tsx | 14 ++++++++------ src/client/views/pdf/Annotation.scss | 3 +++ src/client/views/pdf/PDFViewer.tsx | 13 +++++++------ src/fields/Doc.ts | 2 +- 15 files changed, 80 insertions(+), 66 deletions(-) (limited to 'src/client/views/linking/LinkEditor.tsx') diff --git a/src/Utils.ts b/src/Utils.ts index 6eacd8296..e11f1154e 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -125,7 +125,9 @@ export namespace Utils { // bcz: isTransparent(__value__) is a hack. it would be nice to have acual functions be parsed, but now Doc.matchFieldValue is hardwired to recognize just this one return `backgroundColor:${isTransparentFunctionHack},${noRecursionHack}:x`;// bcz: hack. noRecursion should probably be either another ':' delimited field, or it should be a modifier to the comparision (eg., check, x, etc) field } - + export function PropUnsetFilter(prop: string) { + return `${prop}:any,${noRecursionHack}:unset`; + } export function toRGBAstr(col: { r: number, g: number, b: number, a?: number }) { return "rgba(" + col.r + "," + col.g + "," + col.b + (col.a !== undefined ? "," + col.a : "") + ")"; diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index e498a7cca..3b376a0e7 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -241,6 +241,7 @@ export namespace DocServer { // the field has been returned from the server const getSerializedField = Utils.EmitCallback(_socket, MessageStore.GetRefField, id); + console.log(id) // when the serialized RefField has been received, go head and begin deserializing it into an object. // Here, once deserialized, we also invoke .proto to 'load' the document's prototype, which ensures that all // future .proto calls on the Doc won't have to go farther than the cache to get their actual value. @@ -264,6 +265,7 @@ export namespace DocServer { } else { delete _cache[id]; } + console.log(id, field); return field; // either way, overwrite or delete any promises cached at this id (that we inserted as flags // to indicate that the field was in the process of being fetched). Now everything diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f50f306a3..e8185400e 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -962,13 +962,17 @@ export namespace DocUtils { // metadata facets that exist const exists = Object.keys(facet).filter(value => facet[value] === "exists"); + // metadata facets that exist + const unsets = Object.keys(facet).filter(value => facet[value] === "unset"); + // facets that have an x next to them const xs = Object.keys(facet).filter(value => facet[value] === "x"); - if (!exists.length && !xs.length && !checks.length && !matches.length) return true; + if (!unsets.length && !exists.length && !xs.length && !checks.length && !matches.length) return true; const failsNotEqualFacets = !xs.length ? false : xs.some(value => Doc.matchFieldValue(d, facetKey, value)); const satisfiesCheckFacets = !checks.length ? true : checks.some(value => Doc.matchFieldValue(d, facetKey, value)); const satisfiesExistsFacets = !exists.length ? true : exists.some(value => d[facetKey] !== undefined); + const satisfiesUnsetsFacets = !unsets.length ? true : unsets.some(value => d[facetKey] === undefined); const satisfiesMatchFacets = !matches.length ? true : matches.some(value => { if (facetKey.startsWith("*")) { // fields starting with a '*' are used to match families of related fields. ie, *lastModified will match text-lastModified, data-lastModified, etc const allKeys = Array.from(Object.keys(d)); @@ -980,11 +984,11 @@ export namespace DocUtils { }); // if we're ORing them together, the default return is false, and we return true for a doc if it satisfies any one set of criteria if ((parentCollection?.currentFilter as Doc)?.filterBoolean === "OR") { - if (satisfiesExistsFacets && satisfiesCheckFacets && !failsNotEqualFacets && satisfiesMatchFacets) return true; + if (satisfiesUnsetsFacets && satisfiesExistsFacets && satisfiesCheckFacets && !failsNotEqualFacets && satisfiesMatchFacets) return true; } // if we're ANDing them together, the default return is true, and we return false for a doc if it doesn't satisfy any set of criteria else { - if (!satisfiesExistsFacets || !satisfiesCheckFacets || failsNotEqualFacets || (matches.length && !satisfiesMatchFacets)) return false; + if (!satisfiesUnsetsFacets || !satisfiesExistsFacets || !satisfiesCheckFacets || failsNotEqualFacets || (matches.length && !satisfiesMatchFacets)) return false; } } @@ -1088,10 +1092,11 @@ export namespace DocUtils { "anchor2-useLinkSmallAnchor": target.doc.useLinkSmallAnchor ? true : undefined, "acl-Public": SharingPermissions.Augment, "_acl-Public": SharingPermissions.Augment, - layout_linkView: Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null), - linkDisplay: true, hidden: true, + linkDisplay: true, + hidden: true, linkRelationship, - _layoutKey: "layout_linkView", + _showCaption: "description", + _showTitle: "linkRelationship", description }, id), showPopup); } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 5c9c8063b..38e027fb3 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -246,12 +246,6 @@ export class CollectionView extends ViewBoxAnnotatableComponent this.props.childLayoutTemplate?.() || Cast(this.rootDoc.childLayoutTemplate, Doc, null); @computed get childLayoutString() { return StrCast(this.rootDoc.childLayoutString); } - /** - * Shows the filter icon if it's a user-created collection which isn't a dashboard and has some docFilters applied on it or on the current dashboard. - */ - @computed get showFilterIcon() { - return this.props.Document.viewType !== CollectionViewType.Docking && !Doc.IsSystem(this.props.Document) && this._subView?.IsFiltered(); - } @observable _subView: any = undefined; @@ -280,12 +274,6 @@ export class CollectionView extends ViewBoxAnnotatableComponent {this.showIsTagged()} {this.collectionViewType !== undefined ? this.SubView(this.collectionViewType, props) : (null)} - {this.showFilterIcon ? - { this.props.select(false); CurrentUserUtils.propertiesWidth = 250; e.stopPropagation(); })} - /> - : (null)}
); } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 3b3e069d8..2cb487588 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -1,6 +1,6 @@ import { action, computed, IReactionDisposer, observable, reaction } from "mobx"; import { observer } from "mobx-react"; -import { Doc } from "../../../../fields/Doc"; +import { Doc, Field } from "../../../../fields/Doc"; import { Id } from "../../../../fields/FieldSymbols"; import { List } from "../../../../fields/List"; import { NumCast, StrCast } from "../../../../fields/Types"; @@ -180,7 +180,7 @@ export class CollectionFreeFormLinkView extends React.Component; const linkColorList = Doc.UserDoc().linkColorList as List; //access stroke color using index of the relationship in the color list (default black) @@ -189,7 +189,7 @@ export class CollectionFreeFormLinkView extends React.Component {textX === undefined ? (null) : - {StrCast(this.props.LinkDocs[0].description)} + {Field.toString(this.props.LinkDocs[0].description as any as Field)} } ); } diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx index 240a71c3e..219f7d3a2 100644 --- a/src/client/views/linking/LinkEditor.tsx +++ b/src/client/views/linking/LinkEditor.tsx @@ -2,13 +2,14 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Tooltip } from "@material-ui/core"; import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; -import { Doc, StrListCast } from "../../../fields/Doc"; -import { DateCast, StrCast } from "../../../fields/Types"; +import { Doc, StrListCast, Field } from "../../../fields/Doc"; +import { DateCast, StrCast, Cast } from "../../../fields/Types"; import { LinkManager } from "../../util/LinkManager"; import { undoBatch } from "../../util/UndoManager"; import './LinkEditor.scss'; import { LinkRelationshipSearch } from "./LinkRelationshipSearch"; import React = require("react"); +import { ToString } from "../../../fields/FieldSymbols"; interface LinkEditorProps { @@ -20,7 +21,7 @@ interface LinkEditorProps { @observer export class LinkEditor extends React.Component { - @observable description = StrCast(LinkManager.currentLink?.description); + @observable description = Field.toString(LinkManager.currentLink?.description as any as Field); @observable relationship = StrCast(LinkManager.currentLink?.linkRelationship); @observable openDropdown: boolean = false; @observable showInfo: boolean = false; @@ -41,7 +42,7 @@ export class LinkEditor extends React.Component { @undoBatch setRelationshipValue = action((value: string) => { if (LinkManager.currentLink) { - LinkManager.currentLink.linkRelationship = value; + Doc.GetProto(LinkManager.currentLink).linkRelationship = value; const linkRelationshipList = StrListCast(Doc.UserDoc().linkRelationshipList); const linkColorList = StrListCast(Doc.UserDoc().linkColorList); // if the relationship does not exist in the list, add it and a corresponding unique randomly generated color @@ -79,7 +80,7 @@ export class LinkEditor extends React.Component { @undoBatch setDescripValue = action((value: string) => { if (LinkManager.currentLink) { - LinkManager.currentLink.description = value; + Doc.GetProto(LinkManager.currentLink).description = value; this.buttonColor = "rgb(62, 133, 55)"; setTimeout(action(() => this.buttonColor = ""), 750); return true; diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index 6708a08ee..72c7e4f45 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -15,6 +15,7 @@ import "./ComparisonBox.scss"; import { DocumentView, DocumentViewProps } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import React = require("react"); +import { DocumentType } from '../../documents/DocumentTypes'; export const comparisonSchema = createSchema({}); @@ -87,7 +88,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent; }; const displayDoc = (which: string) => { - const whichDoc = Cast(this.dataDoc[`compareBox-${which}`], Doc, null); + var whichDoc = Cast(this.dataDoc[which], Doc, null); + if (whichDoc.type === DocumentType.MARKER) whichDoc = Cast(whichDoc.annotationOn, Doc, null); return whichDoc ? <> - {displayBox("after", 1, this.props.PanelWidth() - 3)} + {displayBox(this.fieldKey === "data" ? "compareBox-after" : `${this.fieldKey}2`, 1, this.props.PanelWidth() - 3)}
- {displayBox("before", 0, 0)} + {displayBox(this.fieldKey === "data" ? "compareBox-before" : `${this.fieldKey}1`, 0, 0)}
(this.props.PanelWidth() - 5) / this.props.PanelWidth() ? "w-resize" : undefined }} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 46a8b6629..35249c7f4 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -13,7 +13,7 @@ import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Ty import { AudioField } from "../../../fields/URLField"; import { GetEffectiveAcl, SharingPermissions, TraceMobx } from '../../../fields/util'; import { MobileInterface } from '../../../mobile/MobileInterface'; -import { emptyFunction, hasDescendantTarget, OmitKeys, returnTrue, returnVal, Utils, lightOrDark, simulateMouseClick } from "../../../Utils"; +import { emptyFunction, hasDescendantTarget, OmitKeys, returnTrue, returnVal, Utils, lightOrDark, simulateMouseClick, returnEmptyString } from "../../../Utils"; import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; import { Docs, DocUtils } from "../../documents/Documents"; import { DocumentType } from '../../documents/DocumentTypes'; @@ -802,6 +802,12 @@ export class DocumentViewInternal extends DocComponent StrListCast(this.props.Document._docFilters); + collectionRangeDocFilters = () => StrListCast(this.props.Document._docRangeFilters); + @computed get showFilterIcon() { + return this.collectionFilters().length || this.collectionRangeDocFilters().length ? "hasFilter" : + this.props.docFilters?.().filter(f => Utils.IsRecursiveFilter(f)).length || this.props.docRangeFilters().length ? "inheritsFilter" : undefined + } rootSelected = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; panelHeight = () => this.props.PanelHeight() - this.headerMargin; screenToLocal = () => this.props.ScreenToLocalTransform().translate(0, -this.headerMargin); @@ -832,7 +838,7 @@ export class DocumentViewInternal extends DocComponent; return
this.props.PanelHeight() || 1; anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { switch (property) { + case StyleProp.ShowTitle: return ""; case StyleProp.PointerEvents: return "none"; case StyleProp.LinkSource: return this.props.Document;// pass the LinkSource to the LinkAnchorBox default: return this.props.styleProvider?.(doc, props, property); @@ -901,6 +908,8 @@ export class DocumentViewInternal extends DocComponent } + {this.showFilterIcon ? + { this.props.select(false); CurrentUserUtils.propertiesWidth = 250; e.stopPropagation(); })} + /> + : (null)}
; } } diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index 55ea45bb8..b82d16677 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -2,10 +2,10 @@ import React = require("react"); import { observer } from "mobx-react"; import { documentSchema } from "../../../fields/documentSchemas"; import { makeInterface } from "../../../fields/Schema"; -import { returnFalse } from "../../../Utils"; -import { CollectionTreeView } from "../collections/CollectionTreeView"; +import { emptyFunction, returnFalse } from "../../../Utils"; import { ViewBoxBaseComponent } from "../DocComponent"; import { StyleProp } from "../StyleProvider"; +import { ComparisonBox } from "./ComparisonBox"; import { FieldView, FieldViewProps } from './FieldView'; import "./LinkBox.scss"; @@ -20,22 +20,15 @@ export class LinkBox extends ViewBoxBaseComponent( if (this.dataDoc.treeViewOpen === undefined) setTimeout(() => this.dataDoc.treeViewOpen = true); return
- - + moveDocument={returnFalse} />
; } } \ No newline at end of file diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx index b62a4dd56..a9d33f161 100644 --- a/src/client/views/nodes/LinkDescriptionPopup.tsx +++ b/src/client/views/nodes/LinkDescriptionPopup.tsx @@ -1,8 +1,9 @@ import React = require("react"); +import { action, observable } from "mobx"; import { observer } from "mobx-react"; -import "./LinkDescriptionPopup.scss"; -import { observable, action } from "mobx"; +import { Doc } from "../../../fields/Doc"; import { LinkManager } from "../../util/LinkManager"; +import "./LinkDescriptionPopup.scss"; import { TaskCompletionBox } from "./TaskCompletedBox"; @@ -25,7 +26,7 @@ export class LinkDescriptionPopup extends React.Component<{}> { onDismiss = (add: boolean) => { LinkDescriptionPopup.descriptionPopup = false; if (add) { - LinkManager.currentLink && (LinkManager.currentLink.description = this.description); + LinkManager.currentLink && (Doc.GetProto(LinkManager.currentLink).description = this.description); } } diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index f0a502e31..30b4dc92a 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -3,9 +3,9 @@ import { action, computed, IReactionDisposer, observable, reaction, runInAction import { observer } from "mobx-react"; import * as Pdfjs from "pdfjs-dist"; import "pdfjs-dist/web/pdf_viewer.css"; -import { Doc, DocListCast, Opt, WidthSym } from "../../../fields/Doc"; +import { Doc, DocListCast, Opt, WidthSym, StrListCast } from "../../../fields/Doc"; import { documentSchema } from '../../../fields/documentSchemas'; -import { makeInterface } from "../../../fields/Schema"; +import { makeInterface, listSpec } from "../../../fields/Schema"; import { Cast, NumCast, StrCast } from '../../../fields/Types'; import { PdfField } from "../../../fields/URLField"; import { TraceMobx } from '../../../fields/util'; @@ -25,6 +25,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import { pageSchema } from "./ImageBox"; import "./PDFBox.scss"; import React = require("react"); +import { CurrentUserUtils } from '../../util/CurrentUserUtils'; type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, typeof pageSchema]>; const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema); @@ -249,9 +250,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent { - return 1; - } + contentScaling = () => 1; @computed get renderPdfView() { TraceMobx(); const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 6a20ca14a..60a83d612 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -532,7 +532,8 @@ export class WebBox extends ViewBoxAnnotatableComponent {this.urlContent}
; @@ -575,10 +576,11 @@ export class WebBox extends ViewBoxAnnotatableComponent this.props.PanelHeight() / (this.props.scaling?.() || 1); // () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document); scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop)); anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; - transparentFilter = () => [...this.props.docFilters(), Utils.IsTransparentFilter()]; - opaqueFilter = () => [...this.props.docFilters(), Utils.IsOpaqueFilter()]; + basicFilter = () => [...this.props.docFilters(), Utils.PropUnsetFilter("textInlineAnnotations")]; + transparentFilter = () => [Utils.IsTransparentFilter(), ...this.basicFilter()]; + opaqueFilter = () => [Utils.IsOpaqueFilter(), ...this.basicFilter()]; render() { - const pointerEvents = this.props.layerProvider?.(this.layoutDoc) === false ? "none" : undefined; + const pointerEvents = this.props.layerProvider?.(this.layoutDoc) === false ? "none" : this.props.pointerEvents ? this.props.pointerEvents as any : undefined; const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1; const scale = previewScale * (this.props.scaling?.() || 1); const renderAnnotations = (docFilters?: () => string[]) => @@ -593,7 +595,7 @@ export class WebBox extends ViewBoxAnnotatableComponent; return (
+ style={{ pointerEvents: this.props.isContentActive() && this.props.pointerEvents !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" : SnappingManager.GetIsDragging() ? undefined : "none" }} >
{ let focusSpeed: Opt; if (doc !== this.props.rootDoc && mainCont) { const windowHeight = this.props.PanelHeight() / (this.props.scaling?.() || 1); - const scrollTo = Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.props.layoutDoc._scrollTop), windowHeight, .1 * windowHeight); + const scrollTo = doc.unrendered ? NumCast(doc.y) : Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.props.layoutDoc._scrollTop), windowHeight, .1 * windowHeight); if (scrollTo !== undefined) { focusSpeed = 500; @@ -502,8 +502,9 @@ export class PDFViewer extends React.Component { overlayTransform = () => this.scrollXf().scale(1 / this._zoomed); panelWidth = () => this.props.PanelWidth() / (this.props.scaling?.() || 1); // (this.Document.scrollHeight || Doc.NativeHeight(this.Document) || 0); panelHeight = () => this.props.PanelHeight() / (this.props.scaling?.() || 1); // () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document); - transparentFilter = () => [...this.props.docFilters(), Utils.IsTransparentFilter()]; - opaqueFilter = () => [...this.props.docFilters(), Utils.IsOpaqueFilter()]; + basicFilter = () => [...this.props.docFilters(), Utils.PropUnsetFilter("textInlineAnnotations")]; + transparentFilter = () => [Utils.IsTransparentFilter(), ...this.basicFilter()]; + opaqueFilter = () => [Utils.IsOpaqueFilter(), ...this.basicFilter()]; @computed get overlayLayer() { const renderAnnotations = (docFilters?: () => string[]) => { select={emptyFunction} ContentScaling={this.contentZoom} bringToFront={emptyFunction} - docFilters={docFilters || this.props.docFilters} + docFilters={docFilters || this.basicFilter} dontRenderDocuments={docFilters ? false : true} CollectionView={undefined} ScreenToLocalTransform={this.overlayTransform} @@ -543,7 +544,7 @@ export class PDFViewer extends React.Component {
; } @computed get pdfViewerDiv() { - return
; + return
; } @computed get contentScaling() { return this.props.ContentScaling?.() || 1; } @computed get standinViews() { @@ -556,7 +557,7 @@ export class PDFViewer extends React.Component { render() { TraceMobx(); return
-
, key: string, value: any, modifiers: "remove" | "match" | "check" | "x" | "exists", toggle?: boolean, fieldSuffix?: string, append: boolean = true) { + export function setDocFilter(container: Opt, key: string, value: any, modifiers: "remove" | "match" | "check" | "x" | "exists" | "unset", toggle?: boolean, fieldSuffix?: string, append: boolean = true) { if (!container) return; const filterField = "_" + (fieldSuffix ? fieldSuffix + "-" : "") + "docFilters"; const docFilters = Cast(container[filterField], listSpec("string"), []); -- cgit v1.2.3-70-g09d2 From 4e6a1d7a37c8c28014a9f7cd0d92f17c8f29454d Mon Sep 17 00:00:00 2001 From: geireann Date: Thu, 23 Sep 2021 19:30:52 +0000 Subject: Revert "Merge pull request #34 from brown-dash/linking-anh" This reverts commit 70d80e30de9963c353636d9780ffb83f3285aac7, reversing changes made to d5f9533d153e11e24d2ab7c03b4561170f0768fe. --- src/client/documents/Documents.ts | 1 - src/client/util/LinkManager.ts | 2 -- .../CollectionFreeFormLinkView.tsx | 15 +++------------ src/client/views/linking/LinkEditor.tsx | 20 ++------------------ src/client/views/linking/LinkMenuItem.tsx | 4 ++-- src/fields/Doc.ts | 1 - 6 files changed, 7 insertions(+), 36 deletions(-) (limited to 'src/client/views/linking/LinkEditor.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 6fca0b67e..8ac647b99 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -301,7 +301,6 @@ export class DocumentOptions { border?: string; //for searchbox hoverBackgroundColor?: string; // background color of a label when hovered linkRelationshipList?: List; // for storing different link relationships (when set by user in the link editor) - linkRelationshipSizes?: List; //stores number of links contained in each relationship linkColorList?: List; // colors of links corresponding to specific link relationships } export namespace Docs { diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 4c24fbafb..64da68f59 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -103,10 +103,8 @@ export class LinkManager { if (!Doc.UserDoc().linkRelationshipList && !Doc.UserDoc().linkColorList) { const linkRelationshipList = new List(); const linkColorList = new List(); - const linkRelationshipSizes = new List(); Doc.UserDoc().linkRelationshipList = linkRelationshipList; Doc.UserDoc().linkColorList = linkColorList; - Doc.UserDoc().linkRelationshipSizes = linkRelationshipSizes; } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 88cd0feb3..f6c2707da 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -42,7 +42,7 @@ export class CollectionFreeFormLinkView extends React.Component this._opacity = 0.75), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render() + setTimeout(action(() => this._opacity = 1), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render() setTimeout(action(() => (!LinkDocs.length || !linkDoc.linkDisplay) && (this._opacity = 0.05)), 750); // this will unhighlight the link line. const acont = A.ContentDiv.getElementsByClassName("linkAnchorBox-cont"); const bcont = B.ContentDiv.getElementsByClassName("linkAnchorBox-cont"); @@ -180,24 +180,15 @@ export class CollectionFreeFormLinkView extends React.Component; const linkColorList = Doc.UserDoc().linkColorList as List; - const linkRelationshipSizes = Doc.UserDoc().linkRelationshipSizes as List; - const currRelationshipIndex = linkRelationshipList.indexOf(linkRelationship); - //access stroke color using index of the relationship in the color list (default black) - const strokeColor = currRelationshipIndex == -1 ? "black" : linkColorList[linkRelationshipList.indexOf(linkRelationship)]; - - //calculate stroke width/thickness based on the relative importance of the relationshipship (i.e. how many links the relationship has) - //thickness varies linearly from 3px to 12px for increasing link count - const strokeWidth: string = currRelationshipIndex == -1 ? "3px" : Math.floor(2 + 10 * (linkRelationshipSizes[currRelationshipIndex] / Math.max(...linkRelationshipSizes))) + "px"; - + const strokeColor = linkRelationshipList.indexOf(linkRelationship) === -1 ? (CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "white" : "black") : linkColorList[linkRelationshipList.indexOf(linkRelationship)]; return !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<> - {textX === undefined ? (null) : {Field.toString(this.props.LinkDocs[0].description as any as Field)} diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx index 58c57a23b..219f7d3a2 100644 --- a/src/client/views/linking/LinkEditor.tsx +++ b/src/client/views/linking/LinkEditor.tsx @@ -2,7 +2,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Tooltip } from "@material-ui/core"; import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; -import { Doc, NumListCast, StrListCast, Field } from "../../../fields/Doc"; +import { Doc, StrListCast, Field } from "../../../fields/Doc"; import { DateCast, StrCast, Cast } from "../../../fields/Types"; import { LinkManager } from "../../util/LinkManager"; import { undoBatch } from "../../util/UndoManager"; @@ -42,28 +42,14 @@ export class LinkEditor extends React.Component { @undoBatch setRelationshipValue = action((value: string) => { if (LinkManager.currentLink) { - const prevRelationship = LinkManager.currentLink.linkRelationship as string; - LinkManager.currentLink.linkRelationship = value; Doc.GetProto(LinkManager.currentLink).linkRelationship = value; const linkRelationshipList = StrListCast(Doc.UserDoc().linkRelationshipList); - const linkRelationshipSizes = NumListCast(Doc.UserDoc().linkRelationshipSizes); const linkColorList = StrListCast(Doc.UserDoc().linkColorList); - // if the relationship does not exist in the list, add it and a corresponding unique randomly generated color if (linkRelationshipList && !linkRelationshipList.includes(value)) { linkRelationshipList.push(value); - linkRelationshipSizes.push(1); const randColor = "rgb(" + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + ")"; - linkColorList.push(randColor) - // if the relationship is already in the list AND the new rel is different from the prev rel, update the rel sizes - } else if (linkRelationshipList && value != prevRelationship) { - //increment size of new relationship size - linkRelationshipSizes[linkRelationshipList.indexOf(value)] = linkRelationshipSizes[linkRelationshipList.indexOf(value)] + 1; - //decrement the size of the previous relationship if it already exists (i.e. not default 'link' relationship upon link creation) - if (linkRelationshipList.includes(prevRelationship)) { - linkRelationshipSizes[linkRelationshipList.indexOf(prevRelationship)] = linkRelationshipSizes[linkRelationshipList.indexOf(prevRelationship)] - 1; - } - + linkColorList.push(randColor); } this.relationshipButtonColor = "rgb(62, 133, 55)"; setTimeout(action(() => this.relationshipButtonColor = ""), 750); @@ -155,7 +141,6 @@ export class LinkEditor extends React.Component { style={{ width: "100%" }} id="input" value={this.relationship} - autoComplete={"off"} placeholder={"Enter link relationship"} onKeyDown={this.onRelationshipKey} onChange={this.handleRelationshipChange} @@ -184,7 +169,6 @@ export class LinkEditor extends React.Component {
{
{this.props.linkDoc.hidden ? "Show Anchor" : "Hide Anchor"}
}>
e.stopPropagation()}> -
+
{!this.props.linkDoc.linkDisplay ? "Show link" : "Hide link"}
}>
e.stopPropagation()}> -
+
{!this.props.linkDoc.linkAutoMove ? "Auto move dot" : "Freeze dot position"}
}> diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 5133da603..57bd0f46f 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -80,7 +80,6 @@ export function DocListCastAsync(field: FieldResult, defaultValue?: Doc[]) { export async function DocCastAsync(field: FieldResult): Promise> { return Cast(field, Doc); } -export function NumListCast(field: FieldResult) { return Cast(field, listSpec("number"), []); } export function StrListCast(field: FieldResult) { return Cast(field, listSpec("string"), []); } export function DocListCast(field: FieldResult) { return Cast(field, listSpec(Doc), []).filter(d => d instanceof Doc) as Doc[]; } export function DocListCastOrNull(field: FieldResult) { return Cast(field, listSpec(Doc), null)?.filter(d => d instanceof Doc) as Doc[] | undefined; } -- cgit v1.2.3-70-g09d2 From 43496b4cd19a06d2682f2416a4273e25cdcb55a0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 7 Oct 2021 08:47:22 -0400 Subject: Revert "Revert "Merge pull request #34 from brown-dash/linking-anh"" This reverts commit 4e6a1d7a37c8c28014a9f7cd0d92f17c8f29454d. --- src/client/documents/Documents.ts | 1 + src/client/util/LinkManager.ts | 2 ++ .../CollectionFreeFormLinkView.tsx | 15 ++++++++++++--- src/client/views/linking/LinkEditor.tsx | 20 ++++++++++++++++++-- src/client/views/linking/LinkMenuItem.tsx | 4 ++-- src/fields/Doc.ts | 1 + 6 files changed, 36 insertions(+), 7 deletions(-) (limited to 'src/client/views/linking/LinkEditor.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index e3623c069..6d64b3286 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -302,6 +302,7 @@ export class DocumentOptions { border?: string; //for searchbox hoverBackgroundColor?: string; // background color of a label when hovered linkRelationshipList?: List; // for storing different link relationships (when set by user in the link editor) + linkRelationshipSizes?: List; //stores number of links contained in each relationship linkColorList?: List; // colors of links corresponding to specific link relationships } export namespace Docs { diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 53bd13fb3..3f7f16113 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -107,8 +107,10 @@ export class LinkManager { if (!Doc.UserDoc().linkRelationshipList && !Doc.UserDoc().linkColorList) { const linkRelationshipList = new List(); const linkColorList = new List(); + const linkRelationshipSizes = new List(); Doc.UserDoc().linkRelationshipList = linkRelationshipList; Doc.UserDoc().linkColorList = linkColorList; + Doc.UserDoc().linkRelationshipSizes = linkRelationshipSizes; } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index f6c2707da..88cd0feb3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -42,7 +42,7 @@ export class CollectionFreeFormLinkView extends React.Component this._opacity = 1), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render() + setTimeout(action(() => this._opacity = 0.75), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render() setTimeout(action(() => (!LinkDocs.length || !linkDoc.linkDisplay) && (this._opacity = 0.05)), 750); // this will unhighlight the link line. const acont = A.ContentDiv.getElementsByClassName("linkAnchorBox-cont"); const bcont = B.ContentDiv.getElementsByClassName("linkAnchorBox-cont"); @@ -180,15 +180,24 @@ export class CollectionFreeFormLinkView extends React.Component; const linkColorList = Doc.UserDoc().linkColorList as List; + const linkRelationshipSizes = Doc.UserDoc().linkRelationshipSizes as List; + const currRelationshipIndex = linkRelationshipList.indexOf(linkRelationship); + //access stroke color using index of the relationship in the color list (default black) - const strokeColor = linkRelationshipList.indexOf(linkRelationship) === -1 ? (CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "white" : "black") : linkColorList[linkRelationshipList.indexOf(linkRelationship)]; + const strokeColor = currRelationshipIndex == -1 ? "black" : linkColorList[linkRelationshipList.indexOf(linkRelationship)]; + + //calculate stroke width/thickness based on the relative importance of the relationshipship (i.e. how many links the relationship has) + //thickness varies linearly from 3px to 12px for increasing link count + const strokeWidth: string = currRelationshipIndex == -1 ? "3px" : Math.floor(2 + 10 * (linkRelationshipSizes[currRelationshipIndex] / Math.max(...linkRelationshipSizes))) + "px"; + return !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<> - {textX === undefined ? (null) : {Field.toString(this.props.LinkDocs[0].description as any as Field)} diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx index 219f7d3a2..58c57a23b 100644 --- a/src/client/views/linking/LinkEditor.tsx +++ b/src/client/views/linking/LinkEditor.tsx @@ -2,7 +2,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Tooltip } from "@material-ui/core"; import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; -import { Doc, StrListCast, Field } from "../../../fields/Doc"; +import { Doc, NumListCast, StrListCast, Field } from "../../../fields/Doc"; import { DateCast, StrCast, Cast } from "../../../fields/Types"; import { LinkManager } from "../../util/LinkManager"; import { undoBatch } from "../../util/UndoManager"; @@ -42,14 +42,28 @@ export class LinkEditor extends React.Component { @undoBatch setRelationshipValue = action((value: string) => { if (LinkManager.currentLink) { + const prevRelationship = LinkManager.currentLink.linkRelationship as string; + LinkManager.currentLink.linkRelationship = value; Doc.GetProto(LinkManager.currentLink).linkRelationship = value; const linkRelationshipList = StrListCast(Doc.UserDoc().linkRelationshipList); + const linkRelationshipSizes = NumListCast(Doc.UserDoc().linkRelationshipSizes); const linkColorList = StrListCast(Doc.UserDoc().linkColorList); + // if the relationship does not exist in the list, add it and a corresponding unique randomly generated color if (linkRelationshipList && !linkRelationshipList.includes(value)) { linkRelationshipList.push(value); + linkRelationshipSizes.push(1); const randColor = "rgb(" + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + ")"; - linkColorList.push(randColor); + linkColorList.push(randColor) + // if the relationship is already in the list AND the new rel is different from the prev rel, update the rel sizes + } else if (linkRelationshipList && value != prevRelationship) { + //increment size of new relationship size + linkRelationshipSizes[linkRelationshipList.indexOf(value)] = linkRelationshipSizes[linkRelationshipList.indexOf(value)] + 1; + //decrement the size of the previous relationship if it already exists (i.e. not default 'link' relationship upon link creation) + if (linkRelationshipList.includes(prevRelationship)) { + linkRelationshipSizes[linkRelationshipList.indexOf(prevRelationship)] = linkRelationshipSizes[linkRelationshipList.indexOf(prevRelationship)] - 1; + } + } this.relationshipButtonColor = "rgb(62, 133, 55)"; setTimeout(action(() => this.relationshipButtonColor = ""), 750); @@ -141,6 +155,7 @@ export class LinkEditor extends React.Component { style={{ width: "100%" }} id="input" value={this.relationship} + autoComplete={"off"} placeholder={"Enter link relationship"} onKeyDown={this.onRelationshipKey} onChange={this.handleRelationshipChange} @@ -169,6 +184,7 @@ export class LinkEditor extends React.Component {
{
{this.props.linkDoc.hidden ? "Show Anchor" : "Hide Anchor"}
}>
e.stopPropagation()}> -
+
{!this.props.linkDoc.linkDisplay ? "Show link" : "Hide link"}
}>
e.stopPropagation()}> -
+
{!this.props.linkDoc.linkAutoMove ? "Auto move dot" : "Freeze dot position"}
}> diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 9490edc2c..a89bdf57a 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -79,6 +79,7 @@ export function DocListCastAsync(field: FieldResult, defaultValue?: Doc[]) { export async function DocCastAsync(field: FieldResult): Promise> { return Cast(field, Doc); } +export function NumListCast(field: FieldResult) { return Cast(field, listSpec("number"), []); } export function StrListCast(field: FieldResult) { return Cast(field, listSpec("string"), []); } export function DocListCast(field: FieldResult) { return Cast(field, listSpec(Doc), []).filter(d => d instanceof Doc) as Doc[]; } export function DocListCastOrNull(field: FieldResult) { return Cast(field, listSpec(Doc), null)?.filter(d => d instanceof Doc) as Doc[] | undefined; } -- cgit v1.2.3-70-g09d2 From 8f1a6266cf0a728ab2b7df11d45a023de266fae4 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 7 Oct 2021 09:43:19 -0400 Subject: link menu ui tweaking. edge case checks for linkrelationship stuff. default links to have linkAutoMove --- src/Utils.ts | 2 +- src/client/documents/Documents.ts | 2 ++ src/client/util/LinkManager.ts | 11 +++-------- .../collectionFreeForm/CollectionFreeFormLinkView.tsx | 8 +++++--- src/client/views/linking/LinkEditor.tsx | 14 +++++++++++--- src/client/views/linking/LinkMenuGroup.tsx | 1 - src/client/views/linking/LinkMenuItem.tsx | 18 +++++++++--------- 7 files changed, 31 insertions(+), 25 deletions(-) (limited to 'src/client/views/linking/LinkEditor.tsx') diff --git a/src/Utils.ts b/src/Utils.ts index 7ec4f69f3..53182cc9c 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -575,7 +575,7 @@ export function simulateMouseClick(element: Element | null | undefined, x: numbe export function DashColor(color: string) { try { - return Color(color.toLowerCase()); + return color ? Color(color.toLowerCase()) : Color("transparent"); } catch (e) { console.log("COLOR error:", e); return Color("red"); diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 6d64b3286..da5c8efa9 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -191,6 +191,7 @@ export class DocumentOptions { opacity?: number; defaultBackgroundColor?: string; _isLinkButton?: boolean; // marks a document as a button that will follow its primary link when clicked + _linkAutoMove?: boolean; // whether link endpoint should move around the edges of a document to make shortest path to other link endpoint isFolder?: boolean; lastFrame?: number; // the last frame of a frame-based collection (e.g., progressive slide) activeFrame?: number; // the active frame of a document in a frame base collection @@ -1106,6 +1107,7 @@ export namespace DocUtils { "_acl-Public": SharingPermissions.Augment, linkDisplay: true, _hidden: true, + _linkAutoMove: true, linkRelationship, _showCaption: "description", _showTitle: "linkRelationship", diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 3f7f16113..90a8f2737 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -104,14 +104,9 @@ export class LinkManager { public createLinkrelationshipLists = () => { //create new lists for link relations and their associated colors if the lists don't already exist - if (!Doc.UserDoc().linkRelationshipList && !Doc.UserDoc().linkColorList) { - const linkRelationshipList = new List(); - const linkColorList = new List(); - const linkRelationshipSizes = new List(); - Doc.UserDoc().linkRelationshipList = linkRelationshipList; - Doc.UserDoc().linkColorList = linkColorList; - Doc.UserDoc().linkRelationshipSizes = linkRelationshipSizes; - } + !Doc.UserDoc().linkRelationshipList && (Doc.UserDoc().linkRelationshipList = new List()); + !Doc.UserDoc().linkColorList && (Doc.UserDoc().linkColorList = new List()); + !Doc.UserDoc().linkRelationshipSizes && (Doc.UserDoc().linkRelationshipSizes = new List()); } public addLink(linkDoc: Doc, checkExists = false) { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 88cd0feb3..bb4cae8c6 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -189,15 +189,17 @@ export class CollectionFreeFormLinkView extends React.Component; const currRelationshipIndex = linkRelationshipList.indexOf(linkRelationship); + const linkSize = currRelationshipIndex === -1 || currRelationshipIndex >= linkRelationshipSizes.length ? -1 : linkRelationshipSizes[currRelationshipIndex]; + //access stroke color using index of the relationship in the color list (default black) - const strokeColor = currRelationshipIndex == -1 ? "black" : linkColorList[linkRelationshipList.indexOf(linkRelationship)]; + const stroke = currRelationshipIndex === -1 || currRelationshipIndex >= linkColorList.length ? "black" : linkColorList[currRelationshipIndex]; //calculate stroke width/thickness based on the relative importance of the relationshipship (i.e. how many links the relationship has) //thickness varies linearly from 3px to 12px for increasing link count - const strokeWidth: string = currRelationshipIndex == -1 ? "3px" : Math.floor(2 + 10 * (linkRelationshipSizes[currRelationshipIndex] / Math.max(...linkRelationshipSizes))) + "px"; + const strokeWidth = linkSize === -1 ? "3px" : Math.floor(2 + 10 * (linkSize / Math.max(...linkRelationshipSizes))) + "px"; return !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<> - {textX === undefined ? (null) : {Field.toString(this.props.LinkDocs[0].description as any as Field)} diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx index 58c57a23b..5b5c3cd01 100644 --- a/src/client/views/linking/LinkEditor.tsx +++ b/src/client/views/linking/LinkEditor.tsx @@ -50,18 +50,26 @@ export class LinkEditor extends React.Component { const linkColorList = StrListCast(Doc.UserDoc().linkColorList); // if the relationship does not exist in the list, add it and a corresponding unique randomly generated color - if (linkRelationshipList && !linkRelationshipList.includes(value)) { + if (!linkRelationshipList?.includes(value)) { linkRelationshipList.push(value); linkRelationshipSizes.push(1); const randColor = "rgb(" + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + ")"; linkColorList.push(randColor) // if the relationship is already in the list AND the new rel is different from the prev rel, update the rel sizes } else if (linkRelationshipList && value != prevRelationship) { + const index = linkRelationshipList.indexOf(value); //increment size of new relationship size - linkRelationshipSizes[linkRelationshipList.indexOf(value)] = linkRelationshipSizes[linkRelationshipList.indexOf(value)] + 1; + if (index !== -1 && index < linkRelationshipSizes.length) { + const pvalue = linkRelationshipSizes[index]; + linkRelationshipSizes[index] = (pvalue === undefined || !Number.isFinite(pvalue) ? 1 : pvalue + 1); + } //decrement the size of the previous relationship if it already exists (i.e. not default 'link' relationship upon link creation) if (linkRelationshipList.includes(prevRelationship)) { - linkRelationshipSizes[linkRelationshipList.indexOf(prevRelationship)] = linkRelationshipSizes[linkRelationshipList.indexOf(prevRelationship)] - 1; + const pindex = linkRelationshipList.indexOf(prevRelationship); + if (pindex !== -1 && pindex < linkRelationshipSizes.length) { + const pvalue = linkRelationshipSizes[pindex]; + linkRelationshipSizes[pindex] = Math.max(0, (pvalue === undefined || !Number.isFinite(pvalue) ? 1 : pvalue - 1)); + } } } diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx index cb6571f92..03377ad4e 100644 --- a/src/client/views/linking/LinkMenuGroup.tsx +++ b/src/client/views/linking/LinkMenuGroup.tsx @@ -31,7 +31,6 @@ export class LinkMenuGroup extends React.Component { if (RGBcolor) { //set opacity to 0.25 by modifiying the rgb string color = RGBcolor.slice(0, RGBcolor.length - 1) + ", 0.25)"; - console.log(color); } } return color; diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index e0b20ef6f..f19064e49 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -165,19 +165,19 @@ export class LinkMenuItem extends React.Component {
-
{this.props.linkDoc.hidden ? "Show Anchor" : "Hide Anchor"}
}> -
e.stopPropagation()}> -
+
{this.props.linkDoc.hidden ? "Show Link Anchor" : "Hide Link Anchor"}
}> +
e.stopPropagation()}> +
-
{!this.props.linkDoc.linkDisplay ? "Show link" : "Hide link"}
}> -
e.stopPropagation()}> -
+
{this.props.linkDoc.linkDisplay ? "Hide Link Line" : "Show Link Line"}
}> +
e.stopPropagation()}> +
-
{!this.props.linkDoc.linkAutoMove ? "Auto move dot" : "Freeze dot position"}
}> -
e.stopPropagation()}> -
+
{this.props.linkDoc.linkAutoMove ? "Click to freeze link anchor position" : "Click to auto move link anchor"}
}> +
e.stopPropagation()}> +
Edit Link
}> -- cgit v1.2.3-70-g09d2