From af8df1fc1af11318cadf1b71373bef776461a5cc Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 6 Apr 2022 10:42:36 -0400
Subject: uses linkMenu in propertiesWindow now.  updated linkMenu api, changed
 layout, made groups collapsible

---
 src/client/views/SidebarAnnos.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/client/views/SidebarAnnos.tsx')

diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index 62f6e388f..fae385660 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -61,7 +61,7 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
         FormattedTextBox.SelectOnLoad = target[Id];
         FormattedTextBox.DontSelectInitialText = true;
         this.allMetadata.map(tag => target[tag] = tag);
-        DocUtils.MakeLink({ doc: anchor }, { doc: target }, "inline markup", "annotation");
+        DocUtils.MakeLink({ doc: anchor }, { doc: target }, "inline markup");
         this.addDocument(target);
         this._stackRef.current?.focusDocument(target);
     }
-- 
cgit v1.2.3-70-g09d2


From cb59842fcb79af7ef72443e08c6a479c3f0af343 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 25 Apr 2022 20:20:48 -0400
Subject:  changed freeformview's with engines to not allow children to be
 edited using setHeight prop since engine layouts are temporary and shouldn't
 edit the doc.  fixed tags to work with pivot view. cleaned up pile views to
 be less hacky..

---
 src/client/documents/Documents.ts                  | 27 +++++++++++++---------
 src/client/views/MainView.tsx                      |  1 +
 src/client/views/SidebarAnnos.tsx                  |  2 +-
 .../views/collections/CollectionPileView.tsx       |  4 ++--
 .../views/collections/CollectionStackingView.tsx   |  6 ++---
 src/client/views/collections/CollectionSubView.tsx |  2 +-
 .../views/collections/CollectionTreeView.tsx       |  2 +-
 src/client/views/collections/TreeView.tsx          |  1 +
 .../CollectionFreeFormLayoutEngines.tsx            | 26 +++++++++++++--------
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  4 +++-
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  5 +---
 src/client/views/nodes/DocumentContentsView.tsx    |  2 +-
 src/client/views/nodes/DocumentView.tsx            | 17 +++++++-------
 src/client/views/nodes/FieldView.tsx               |  2 +-
 src/client/views/nodes/LinkDocPreview.tsx          |  1 +
 src/client/views/nodes/WebBox.tsx                  |  2 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |  2 +-
 src/client/views/pdf/PDFViewer.tsx                 |  2 +-
 src/fields/Doc.ts                                  |  2 +-
 19 files changed, 62 insertions(+), 48 deletions(-)

(limited to 'src/client/views/SidebarAnnos.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 49e53a214..a19530c92 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -14,7 +14,7 @@ import { Cast, NumCast, StrCast } from "../../fields/Types";
 import { AudioField, ImageField, MapField, PdfField, VideoField, WebField, YoutubeField } from "../../fields/URLField";
 import { SharingPermissions } from "../../fields/util";
 import { Upload } from "../../server/SharedMediaTypes";
-import { OmitKeys, Utils } from "../../Utils";
+import { OmitKeys, Utils, aggregateBounds } from "../../Utils";
 import { YoutubeBox } from "../apis/youtube/YoutubeBox";
 import { DocServer } from "../DocServer";
 import { Networking } from "../Network";
@@ -1352,26 +1352,31 @@ export namespace DocUtils {
         if (layoutKey && layoutKey !== "layout" && layoutKey !== "layout_icon") doc.deiconifyLayout = layoutKey.replace("layout_", "");
     }
 
-    export function pileup(docList: Doc[], x?: number, y?: number, create: boolean = true) {
+    export function pileup(docList: Doc[], x?: number, y?: number, size: number = 55, create: boolean = true) {
         let w = 0, h = 0;
         runInAction(() => {
             docList.forEach(d => {
                 DocUtils.iconify(d);
-                w = Math.max(d[WidthSym](), w);
-                h = Math.max(d[HeightSym](), h);
+                w = Math.max(NumCast(d._width), w);
+                h = Math.max(NumCast(d._height), h);
             });
-            h = Math.max(h, w * 4 / 3); // converting to an icon does not update the height right away.  so this is a fallback hack to try to do something reasonable
             docList.forEach((d, i) => {
-                d.x = Math.cos(Math.PI * 2 * i / docList.length) * 10 - w / 2;
-                d.y = Math.sin(Math.PI * 2 * i / docList.length) * 10 - h / 2;
+                d.x = Math.cos(Math.PI * 2 * i / docList.length) * size;
+                d.y = Math.sin(Math.PI * 2 * i / docList.length) * size;
+                d._timecodeToShow = undefined;  // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
+            });
+            const aggBounds = aggregateBounds(docList.map(d => ({ x: NumCast(d.x), y: NumCast(d.y), width: NumCast(d._width), height: NumCast(d._height) })), 0, 0);
+            docList.forEach((d, i) => {
+                d.x = NumCast(d.x) - ((aggBounds.r + aggBounds.x) / 2);
+                d.y = NumCast(d.y) - ((aggBounds.b + aggBounds.y) / 2);
                 d._timecodeToShow = undefined;  // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
             });
         });
         if (create) {
-            const newCollection = Docs.Create.PileDocument(docList, { title: "pileup", x: (x || 0) - 55, y: (y || 0) - 55, _width: 110, _height: 100, });
-            newCollection.x = NumCast(newCollection.x) + NumCast(newCollection._width) / 2 - 55;
-            newCollection.y = NumCast(newCollection.y) + NumCast(newCollection._height) / 2 - 55;
-            newCollection._width = newCollection._height = 110;
+            const newCollection = Docs.Create.PileDocument(docList, { title: "pileup", x: (x || 0) - size, y: (y || 0) - size, _width: size * 2, _height: size * 2, });
+            newCollection.x = NumCast(newCollection.x) + NumCast(newCollection._width) / 2 - size;
+            newCollection.y = NumCast(newCollection.y) + NumCast(newCollection._height) / 2 - size;
+            newCollection._width = newCollection._height = size * 2;
             newCollection._jitterRotation = 10;
             return newCollection;
         }
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index a67cb3014..68b4710ed 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -297,6 +297,7 @@ export class MainView extends React.Component {
             searchFilterDocs={returnEmptyDoclist}
             ContainingCollectionView={undefined}
             ContainingCollectionDoc={undefined}
+            suppressSetHeight={true}
             renderDepth={-1}
         />;
     }
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index fae385660..43a02d029 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -88,7 +88,7 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
     removeDocument = (doc: Doc | Doc[]) => this.props.removeDocument(doc, this.sidebarKey);
     docFilters = () => [...StrListCast(this.props.layoutDoc._docFilters), ...StrListCast(this.props.layoutDoc[this.filtersKey])];
     showTitle = () => "title";
-    setHeightCallback = (height: number) => this.props.setHeight(height + this.filtersHeight());
+    setHeightCallback = (height: number) => this.props.setHeight?.(height + this.filtersHeight());
     render() {
         const renderTag = (tag: string) => {
             const active = StrListCast(this.props.rootDoc[this.filtersKey]).includes(`${tag}:${tag}:check`);
diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx
index 8832b0f4a..4489601db 100644
--- a/src/client/views/collections/CollectionPileView.tsx
+++ b/src/client/views/collections/CollectionPileView.tsx
@@ -74,13 +74,13 @@ export class CollectionPileView extends CollectionSubView() {
             this.rootDoc.y = NumCast(this.rootDoc.y) + this.layoutDoc[HeightSym]() / 2 - NumCast(this.layoutDoc._starburstPileHeight, defaultSize) / 2;
             this.layoutDoc._width = NumCast(this.layoutDoc._starburstPileWidth, defaultSize);
             this.layoutDoc._height = NumCast(this.layoutDoc._starburstPileHeight, defaultSize);
-            DocUtils.pileup(this.childDocs, undefined, undefined, false);
+            DocUtils.pileup(this.childDocs, undefined, undefined, NumCast(this.layoutDoc._width) / 2, false);
             this.layoutDoc._panX = 0;
             this.layoutDoc._panY = -10;
             this.props.Document._pileLayoutEngine = 'pass';
         } else {
             const defaultSize = 25;
-            !this.layoutDoc._starburstRadius && (this.layoutDoc._starburstRadius = 500);
+            !this.layoutDoc._starburstRadius && (this.layoutDoc._starburstRadius = 250);
             !this.layoutDoc._starburstDocScale && (this.layoutDoc._starburstDocScale = 2.5);
             if (this.layoutEngine() === 'pass') {
                 this.rootDoc.x = NumCast(this.rootDoc.x) + this.layoutDoc[WidthSym]() / 2 - defaultSize / 2;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 8634ea139..509005b45 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -141,7 +141,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
             () => this.layoutDoc._columnHeaders = new List()
         );
         this._autoHeightDisposer = reaction(() => this.layoutDoc._autoHeight,
-            autoHeight => autoHeight && this.props.setHeight(Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER),
+            autoHeight => autoHeight && this.props.setHeight?.(Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER),
                 this.headerMargin + (this.isStackingView ?
                     Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", "")))) :
                     this.refList.reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0)))));
@@ -408,7 +408,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                                 Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER),
                                     Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", "")))));
                             if (!LightboxView.IsLightboxDocView(this.props.docViewPath())) {
-                                this.props.setHeight(height);
+                                this.props.setHeight?.(height);
                             }
                         }
                     }));
@@ -458,7 +458,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                     this.observer = new _global.ResizeObserver(action((entries: any) => {
                         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);
-                            this.props.setHeight(this.headerMargin + height);
+                            this.props.setHeight?.(this.headerMargin + height);
                         }
                     }));
                     this.observer.observe(ref);
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 5bdd0c0ac..30e0adf24 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -453,7 +453,7 @@ export function CollectionSubView<X>(moreProps?: X) {
                 if (completed) completed(set);
                 else {
                     if (isFreeformView && generatedDocuments.length > 1) {
-                        addDocument(DocUtils.pileup(generatedDocuments, options.x!, options.y!)!);
+                        addDocument(DocUtils.pileup(generatedDocuments, options.x!, options.y!)!,);
                     } else {
                         generatedDocuments.forEach(addDocument);
                     }
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 76da96174..41970eb96 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -88,7 +88,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
             const titleHeight = !this._titleRef ? this.marginTop() : Number(getComputedStyle(this._titleRef).height.replace("px", ""));
             const bodyHeight = Array.from(this.refList).reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), this.marginBot());
             this.layoutDoc._autoHeightMargins = bodyHeight;
-            this.props.setHeight(bodyHeight + titleHeight);
+            this.props.setHeight?.(bodyHeight + titleHeight);
         }
     }
     unobserveHeight = (ref: any) => {
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 6213850d8..b9710b3f5 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -30,6 +30,7 @@ import { CollectionTreeView } from './CollectionTreeView';
 import { CollectionView, CollectionViewType } from './CollectionView';
 import "./TreeView.scss";
 import React = require("react");
+import { KeyValueBox } from '../nodes/KeyValueBox';
 
 export interface TreeViewProps {
     treeView: CollectionTreeView;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 598960af7..16c7df311 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -111,17 +111,17 @@ export function computerStarburstLayout(
     viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[],
     engineProps: any
 ) {
-    const mustFit = pivotDoc[WidthSym]() !== panelDim[0];
+    const mustFit = pivotDoc[WidthSym]() !== panelDim[0]; // if a panel size is set that's not the same as the pivot doc's size, then assume this is in a panel for a content fitting view (like a grid) in which case everything must be scaled to stay within the panel
     const docMap = new Map<string, PoolData>();
-    const burstRadius = mustFit ? panelDim : [NumCast(pivotDoc._starburstRadius, panelDim[0]), NumCast(pivotDoc._starburstRadius, panelDim[1])];
-    const docSize = mustFit ? panelDim[0] * .33 : 75; // assume a icon sized at 75
-    const scaleDim = [burstRadius[0] + docSize, burstRadius[1] + docSize];
+    const docSize = mustFit ? panelDim[0] * .33 : 75; // assume an icon sized at 75
+    const burstRadius = mustFit ? panelDim : [NumCast(pivotDoc._starburstRadius, panelDim[0]) - docSize, NumCast(pivotDoc._starburstRadius, panelDim[1]) - docSize];
+    const scaleDim = [burstRadius[0] * 2 + docSize, burstRadius[1] * 2 + docSize];
     childPairs.forEach(({ layout, data }, i) => {
-        const docSize = layout.layoutKey === "layout_icon" ? mustFit ? panelDim[0] * .33 : 75 : 400; // assume a icon sized at 10750
+        const docSize = layout.layoutKey === "layout_icon" ? (mustFit ? panelDim[0] * .33 : 75) : 400; // assume a icon sized at 75
         const deg = i / childPairs.length * Math.PI * 2;
         docMap.set(layout[Id], {
-            x: Math.cos(deg) * (burstRadius[0] / 3) - docSize / 2,
-            y: Math.sin(deg) * (burstRadius[1] / 3) - docSize * layout[HeightSym]() / layout[WidthSym]() / 2,
+            x: Math.cos(deg) * burstRadius[0] - docSize / 2,
+            y: Math.sin(deg) * burstRadius[1] - docSize * layout[HeightSym]() / layout[WidthSym]() / 2,
             width: docSize,//layout[WidthSym](),
             height: docSize * layout[HeightSym]() / layout[WidthSym](),
             zIndex: NumCast(layout.zIndex),
@@ -129,7 +129,7 @@ export function computerStarburstLayout(
             replica: ""
         });
     });
-    const divider = { type: "div", color: "transparent", x: -burstRadius[0] / 3, y: 0, width: 15, height: 15, payload: undefined };
+    const divider = { type: "div", color: "transparent", x: -burstRadius[0], y: 0, width: 15, height: 15, payload: undefined };
     return normalizeResults(scaleDim, 12, docMap, poolData, viewDefsToJSX, [], 0, [divider]);
 }
 
@@ -267,7 +267,13 @@ export function computePivotLayout(
     });
 
     const dividers = sortedPivotKeys.map((key, i) =>
-        ({ type: "div", color: "lightGray", x: i * pivotAxisWidth * (numCols * expander + gap) - pivotAxisWidth * (expander - 1) / 2, y: -maxColHeight + pivotAxisWidth, width: pivotAxisWidth * numCols * expander, height: maxColHeight, payload: pivotColumnGroups.get(key)!.filters }));
+    ({
+        type: "div", color: "lightGray",
+        x: i * pivotAxisWidth * (numCols * expander + gap) - pivotAxisWidth * (expander - 1) / 2,
+        y: -maxColHeight + pivotAxisWidth, width: pivotAxisWidth * numCols * expander,
+        height: maxColHeight,
+        payload: pivotColumnGroups.get(key)!.filters
+    }));
     groupNames.push(...dividers);
     return normalizeResults(panelDim, max_text, docMap, poolData, viewDefsToJSX, groupNames, 0, []);
 }
@@ -404,7 +410,7 @@ function normalizeResults(
     const grpEles = groupNames.map(gn => ({ x: gn.x, y: gn.y, width: gn.width, height: gn.height }) as ViewDefBounds);
     const docEles = Array.from(docMap.entries()).map(ele => ele[1]);
     const aggBounds = aggregateBounds(extras.concat(grpEles.concat(docEles.map(de => ({ ...de, type: "doc", payload: "" })))).filter(e => e.zIndex !== -99), 0, 0);
-    aggBounds.r = Math.max(minWidth, aggBounds.r - aggBounds.x);
+    aggBounds.r = aggBounds.x + Math.max(minWidth, aggBounds.r - aggBounds.x);
     const wscale = panelDim[0] / (aggBounds.r - aggBounds.x);
     let scale = wscale * (aggBounds.b - aggBounds.y) > panelDim[1] ? (panelDim[1]) / (aggBounds.b - aggBounds.y) : wscale;
     if (Number.isNaN(scale)) scale = 1;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index eaef1b49c..a14405a0b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1158,6 +1158,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             replica={entry.replica}
             renderIndex={renderIndex}
             dataTransition={entry.transition}
+            suppressSetHeight={this.layoutEngine ? true : false}
             renderCutoffProvider={this.renderCutoffProvider}
             ContainingCollectionView={this.props.CollectionView}
             ContainingCollectionDoc={this.props.Document}
@@ -1300,10 +1301,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         return [] as ViewDefResult[];
     }
 
+    @computed get layoutEngine() { return this.props.layoutEngine?.() || StrCast(this.layoutDoc._layoutEngine); }
     @computed get doInternalLayoutComputation() {
         TraceMobx();
         const newPool = new Map<string, PoolData>();
-        switch (this.props.layoutEngine?.() || StrCast(this.layoutDoc._layoutEngine)) {
+        switch (this.layoutEngine) {
             case "pass": return { newPool, computedElementData: this.doEngineLayout(newPool, computerPassLayout) };
             case "timeline": return { newPool, computedElementData: this.doEngineLayout(newPool, computeTimelineLayout) };
             case "pivot": return { newPool, computedElementData: this.doEngineLayout(newPool, computePivotLayout) };
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 3e35039e3..6097425e1 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -17,9 +17,6 @@ import { StyleProp } from "../StyleProvider";
 import "./CollectionFreeFormDocumentView.scss";
 import { DocumentView, DocumentViewProps } from "./DocumentView";
 import React = require("react");
-import { DocumentType } from "../../documents/DocumentTypes";
-import { collectionSchema } from "../../../fields/documentSchemas";
-import { CollectionViewType } from "../collections/CollectionView";
 
 export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
     dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined;
@@ -174,7 +171,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             style={{
                 outline: this.Highlight ? "orange solid 2px" : "",
                 width: this.panelWidth(),
-                height: !this.ShowTitle && this.layoutDoc.autoHeight && this.rootDoc.type === DocumentType.RTF ? undefined : this.panelHeight(),
+                height: this.panelHeight(),
                 transform: this.transform,
                 transition: this.props.dataTransition ? this.props.dataTransition : this.dataProvider ? this.dataProvider.transition : StrCast(this.layoutDoc.dataTransition),
                 zIndex: this.ZInd,
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 005133eb0..d4e8ffc7f 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -112,7 +112,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & Fo
     isSelected: (outsideReaction: boolean) => boolean,
     select: (ctrl: boolean) => void,
     scaling?: () => number,
-    setHeight: (height: number) => void,
+    setHeight?: (height: number) => void,
     layoutKey: string,
 }> {
     @computed get layout(): string {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 504a3afb6..20eabe6a9 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -114,6 +114,7 @@ export interface DocumentViewSharedProps {
     fitContentsToDoc?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _fitToBox property on a Document
     ContainingCollectionView: Opt<CollectionView>;
     ContainingCollectionDoc: Opt<Doc>;
+    suppressSetHeight?: boolean;
     thumbShown?: () => boolean;
     isHovering?: () => boolean;
     setContentView?: (view: DocComponentView) => any;
@@ -842,11 +843,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
     screenToLocal = () => this.props.ScreenToLocalTransform().translate(0, -this.headerMargin);
     contentScaling = () => this.ContentScale;
     onClickFunc = () => this.onClickHandler;
-    setHeight = (height: number) => {
-        if (this.props.renderDepth !== -1) {
-            this.layoutDoc._height = height;
-        }
-    }
+    setHeight = (height: number) => this.layoutDoc._height = height;
     setContentView = action((view: { getAnchor?: () => Doc, forward?: () => boolean, back?: () => boolean }) => this._componentView = view);
     isContentActive = (outsideReaction?: boolean) => {
         return this.props.isContentActive() === false ? false : (
@@ -890,7 +887,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                 setContentView={this.setContentView}
                 scaling={this.contentScaling}
                 PanelHeight={this.panelHeight}
-                setHeight={this.setHeight}
+                setHeight={!this.props.suppressSetHeight ? this.setHeight : undefined}
                 isContentActive={this.isContentActive}
                 ScreenToLocalTransform={this.screenToLocal}
                 rootSelected={this.rootSelected}
@@ -1207,7 +1204,11 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         return this.docView?._componentView?.reverseNativeScaling?.() ? 0 :
             returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions));
     }
-    @computed get shouldNotScale() { return (this.fitWidth && !this.nativeWidth) || this.props.treeViewDoc || [CollectionViewType.Docking].includes(this.Document._viewType as any); }
+    @computed get shouldNotScale() {
+        return (this.fitWidth && !this.nativeWidth) ||
+            this.props.ContainingCollectionView?.collectionViewType === CollectionViewType.Time ||
+            this.props.treeViewDoc || [CollectionViewType.Docking].includes(this.Document._viewType as any);
+    }
     @computed get effectiveNativeWidth() { return this.shouldNotScale ? 0 : (this.nativeWidth || NumCast(this.layoutDoc.width)); }
     @computed get effectiveNativeHeight() { return this.shouldNotScale ? 0 : (this.nativeHeight || NumCast(this.layoutDoc.height)); }
     @computed get nativeScaling() {
@@ -1324,7 +1325,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
                         position: this.props.Document.isInkMask ? "absolute" : undefined,
                         transform: isButton ? undefined : `translate(${this.centeringX}px, ${this.centeringY}px)`,
                         width: isButton || isPresTreeElement ? "100%" : xshift() ?? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%`,
-                        height: (!this.props.ignoreAutoHeight && this.layoutDoc.autoHeight && this.layoutDoc.type === DocumentType.RTF) || isButton || this.props.forceAutoHeight ? undefined : yshift() ?? (this.fitWidth ? `${this.panelHeight}px` :
+                        height: isButton || this.props.forceAutoHeight ? undefined : yshift() ?? (this.fitWidth ? `${this.panelHeight}px` :
                             `${100 * this.effectiveNativeHeight / this.effectiveNativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%`),
                     }}>
                     <DocumentViewInternal {...this.props}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 943b9f153..ae9acfe3f 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -22,7 +22,7 @@ export interface FieldViewProps extends DocumentViewSharedProps {
     isDocumentActive?: () => boolean;
     isSelected: (outsideReaction?: boolean) => boolean;
     scaling?: () => number;
-    setHeight: (height: number) => void;
+    setHeight?: (height: number) => void;
 
     // properties intended to be used from within layout strings (otherwise use the function equivalents that work more efficiently with React)
     pointerEvents?: string;
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index eca2e3cfd..55f6d6059 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -195,6 +195,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
                             ContainingCollectionDoc={undefined}
                             ContainingCollectionView={undefined}
                             renderDepth={-1}
+                            suppressSetHeight={true}
                             PanelWidth={this.width}
                             PanelHeight={this.height}
                             focus={DocUtils.DefaultFocus}
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 0fd193977..eeb7b925b 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -164,7 +164,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
             autoHeight => {
                 if (autoHeight) {
                     this.layoutDoc._nativeHeight = NumCast(this.props.Document[this.props.fieldKey + "-nativeHeight"]);
-                    this.props.setHeight(NumCast(this.props.Document[this.props.fieldKey + "-nativeHeight"]) * (this.props.scaling?.() || 1));
+                    this.props.setHeight?.(NumCast(this.props.Document[this.props.fieldKey + "-nativeHeight"]) * (this.props.scaling?.() || 1));
                 }
             });
 
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index dc1c67bea..710270be4 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1524,7 +1524,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         if (children) {
             const proseHeight = !this.ProseRef ? 0 : children.reduce((p, child) => p + Number(getComputedStyle(child).height.replace("px", "")), margins);
             const scrollHeight = this.ProseRef && Math.min(NumCast(this.layoutDoc.docMaxAutoHeight, proseHeight), proseHeight);
-            if (scrollHeight && this.props.renderDepth && !this.props.dontRegisterView) {  // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation
+            if (this.props.setHeight && scrollHeight && this.props.renderDepth && !this.props.dontRegisterView) {  // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation
                 const setScrollHeight = () => this.rootDoc[this.fieldKey + "-scrollHeight"] = scrollHeight;
                 if (this.rootDoc === this.layoutDoc.doc || this.layoutDoc.resolvedDataDoc) {
                     setScrollHeight();
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 9aaa6e90f..92a69c02b 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -123,7 +123,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
             autoHeight => {
                 if (autoHeight) {
                     this.props.layoutDoc._nativeHeight = NumCast(this.props.Document[this.props.fieldKey + "-nativeHeight"]);
-                    this.props.setHeight(NumCast(this.props.Document[this.props.fieldKey + "-nativeHeight"]) * (this.props.scaling?.() || 1));
+                    this.props.setHeight?.(NumCast(this.props.Document[this.props.fieldKey + "-nativeHeight"]) * (this.props.scaling?.() || 1));
                 }
             });
 
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 15df673f3..63af8401c 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1108,7 +1108,7 @@ export namespace Doc {
         if (typeof value === "string") {
             value = value.replace(`,${Utils.noRecursionHack}`, "");
         }
-        const fieldVal = doc[key];
+        const fieldVal = key === "#" ? (StrCast(doc.tags).includes(":#" + value + ":") ? StrCast(doc.tags) : undefined) : doc[key];
         if (Cast(fieldVal, listSpec("string"), []).length) {
             const vals = Cast(fieldVal, listSpec("string"), []);
             const docs = vals.some(v => (v as any) instanceof Doc);
-- 
cgit v1.2.3-70-g09d2


From 59a22f3a007b201e68ac2f3e1d62e0ca5e66488a Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 28 Apr 2022 12:13:44 -0400
Subject: fixed feedback dragging link button. fixed warnings.  added some
 assymetric linkRelationships.

---
 src/client/documents/Documents.ts                              |  3 ++-
 src/client/util/DocumentManager.ts                             |  2 +-
 src/client/util/LinkManager.ts                                 |  2 +-
 src/client/views/SidebarAnnos.tsx                              |  2 +-
 .../collections/collectionFreeForm/CollectionFreeFormView.tsx  |  2 +-
 .../views/collections/collectionFreeForm/MarqueeView.tsx       |  2 +-
 src/client/views/linking/LinkMenu.tsx                          |  4 +---
 src/client/views/nodes/DocumentLinksButton.scss                |  2 ++
 src/client/views/nodes/DocumentLinksButton.tsx                 | 10 +++++-----
 src/client/views/nodes/DocumentView.tsx                        |  4 ++--
 src/client/views/nodes/ImageBox.tsx                            |  2 +-
 src/client/views/nodes/PDFBox.tsx                              |  4 ++--
 src/client/views/nodes/formattedText/RichTextRules.ts          |  2 +-
 src/client/views/search/SearchBox.tsx                          |  2 +-
 src/server/ApiManagers/UploadManager.ts                        |  4 ++--
 15 files changed, 24 insertions(+), 23 deletions(-)

(limited to 'src/client/views/SidebarAnnos.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 0bb873667..087d32a60 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1094,10 +1094,11 @@ export namespace DocUtils {
     export function MakeLinkToActiveAudio(getSourceDoc: () => Doc, broadcastEvent = true) {
         broadcastEvent && runInAction(() => DocumentManager.Instance.RecordingEvent = DocumentManager.Instance.RecordingEvent + 1);
         return DocUtils.ActiveRecordings.map(audio =>
-            DocUtils.MakeLink({ doc: getSourceDoc() }, { doc: audio.getAnchor() || audio.props.Document }, "recording link", "recording timeline"));
+            DocUtils.MakeLink({ doc: getSourceDoc() }, { doc: audio.getAnchor() || audio.props.Document }, "recording annotation:linked recording", "recording timeline"));
     }
 
     export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", description: string = "", id?: string, allowParCollectionLink?: boolean, showPopup?: number[]) {
+        if (!linkRelationship) linkRelationship = target.doc.type === DocumentType.RTF ? "Commentary:Comments On" : "link";
         const sv = DocumentManager.Instance.getDocumentView(source.doc);
         if (!allowParCollectionLink && sv?.props.ContainingCollectionDoc === target.doc) return;
         if (target.doc === Doc.UserDoc()) return undefined;
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 412d5a169..b6c28d2fe 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -167,7 +167,7 @@ export class DocumentManager {
     ): Promise<void> => {
         originalTarget = originalTarget ?? targetDoc;
         const getFirstDocView = LightboxView.LightboxDoc ? DocumentManager.Instance.getLightboxDocumentView : DocumentManager.Instance.getFirstDocumentView;
-        var docView = getFirstDocView(targetDoc, originatingDoc);
+        const docView = getFirstDocView(targetDoc, originatingDoc);
         const annotatedDoc = Cast(targetDoc.annotationOn, Doc, null);
         const resolvedTarget = targetDoc.type === DocumentType.MARKER ? annotatedDoc ?? targetDoc : targetDoc; // if target is a marker, then focus toggling should apply to the document it's on since the marker itself doesn't have a hidden field
         var wasHidden = resolvedTarget.hidden;
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index 7ba7a1d4c..9445533dc 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -152,7 +152,7 @@ export class LinkManager {
         this.relatedLinker(anchor).forEach(link => {
             if (link.linkRelationship && link.linkRelationship !== "-ungrouped-") {
                 const relation = StrCast(link.linkRelationship);
-                const anchorRelation = relation.indexOf(":") ? relation.split(":")[Doc.AreProtosEqual(Cast(link.anchor1, Doc, null), anchor) ? 0 : 1] : relation;
+                const anchorRelation = relation.indexOf(":") !== -1 ? relation.split(":")[Doc.AreProtosEqual(Cast(link.anchor1, Doc, null), anchor) ? 0 : 1] : relation;
                 const group = anchorGroups.get(anchorRelation);
                 anchorGroups.set(anchorRelation, group ? [...group, link] : [link]);
             } else {
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index 43a02d029..04c0565ea 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -61,7 +61,7 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
         FormattedTextBox.SelectOnLoad = target[Id];
         FormattedTextBox.DontSelectInitialText = true;
         this.allMetadata.map(tag => target[tag] = tag);
-        DocUtils.MakeLink({ doc: anchor }, { doc: target }, "inline markup");
+        DocUtils.MakeLink({ doc: anchor }, { doc: target }, "inline comment:comment on");
         this.addDocument(target);
         this._stackRef.current?.focusDocument(target);
     }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index f0b3d70a0..3f72052ae 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -278,7 +278,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             if (!linkDragData.linkDragView.props.CollectionFreeFormDocumentView?.() || linkDragData.dragDocument.context !== this.props.Document) { // if the source doc view's context isn't this same freeformcollectionlinkDragData.dragDocument.context === this.props.Document
                 const source = Docs.Create.TextDocument("", { _width: 200, _height: 75, x: xp, y: yp, title: "dropped annotation" });
                 this.props.addDocument?.(source);
-                de.complete.linkDocument = DocUtils.MakeLink({ doc: source }, { doc: linkDragData.linkSourceGetAnchor() }, "doc annotation", ""); // TODODO this is where in text links get passed
+                de.complete.linkDocument = DocUtils.MakeLink({ doc: linkDragData.linkSourceGetAnchor() }, { doc: source }, "annotated by:annotation of", ""); // TODODO this is where in text links get passed
             }
             e.stopPropagation();  //  do nothing if link is dropped into any freeform view parent of dragged document
             return true;
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 2174aaf10..5f303b428 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -521,7 +521,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
         });
         const summary = Docs.Create.TextDocument("", { _backgroundColor: "#e2ad32", x: this.Bounds.left, y: this.Bounds.top, isPushpin: true, _width: 200, _height: 200, _fitToBox: true, _showSidebar: true, title: "overview" });
         const portal = Docs.Create.FreeformDocument(selected, { x: this.Bounds.left + 200, y: this.Bounds.top, isGroup: true, backgroundColor: "transparent" });
-        DocUtils.MakeLink({ doc: summary }, { doc: portal }, "summarizing", "");
+        DocUtils.MakeLink({ doc: summary }, { doc: portal }, "summary of:summarized by", "");
 
         portal.hidden = true;
         this.props.addDocument?.(portal);
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index a564c59d3..17d28e886 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -1,9 +1,7 @@
-import { action, computed, IReactionDisposer, observable, reaction } from "mobx";
+import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
 import { Doc } from "../../../fields/Doc";
 import { LinkManager } from "../../util/LinkManager";
-import { SelectionManager } from "../../util/SelectionManager";
-import { DocumentLinksButton } from "../nodes/DocumentLinksButton";
 import { DocumentView } from "../nodes/DocumentView";
 import { LinkDocPreview } from "../nodes/LinkDocPreview";
 import { LinkEditor } from "./LinkEditor";
diff --git a/src/client/views/nodes/DocumentLinksButton.scss b/src/client/views/nodes/DocumentLinksButton.scss
index 9ab3171d3..0f3eb14bc 100644
--- a/src/client/views/nodes/DocumentLinksButton.scss
+++ b/src/client/views/nodes/DocumentLinksButton.scss
@@ -2,7 +2,9 @@
 
 .documentLinksButton-wrapper {
     transform-origin: top left;
+    width: 100%;
 }
+
 .documentLinksButton-menu {
     width: 100%;
     height: 100%;
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index d2e6e8579..7f69adf6c 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -160,8 +160,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
             endLink = endLinkView?.docView?._componentView?.getAnchor?.() || endLink;
             startLink = DocumentLinksButton.StartLinkView?.docView?._componentView?.getAnchor?.() || startLink;
             const linkDoc = DocUtils.MakeLink({ doc: startLink }, { doc: endLink },
-                DocumentLinksButton.AnnotationId ? "hypothes.is annotation" :
-                    endLink.type === DocumentType.RTF ? "Commentary:Comments On" : "link", undefined, undefined, true);
+                DocumentLinksButton.AnnotationId ? "hypothes.is annotation" : undefined, undefined, undefined, true);
 
             LinkManager.currentLink = linkDoc;
 
@@ -245,9 +244,9 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
                 </div>
             </div>
             :
-            <div className="documentLinksButton-menu" ref={this._linkButton}>
+            <div className="documentLinksButton-menu" >
                 {this.props.InMenu && !this.props.StartLink && DocumentLinksButton.StartLink !== this.props.View.props.Document ? //if the origin node is not this node
-                    <div className={"documentLinksButton-endLink"}
+                    <div className={"documentLinksButton-endLink"} ref={this._linkButton}
                         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)}>
                         <FontAwesomeIcon className="documentdecorations-icon" icon="link" />
@@ -256,7 +255,8 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
                 }
                 {
                     this.props.InMenu && this.props.StartLink ? //if link has been started from current node, then set behavior of link button to deactivate linking when clicked again
-                        <div className={`documentLinksButton ${isActive ? `startLink` : ``}`} onPointerDown={isActive ? undefined : this.onLinkButtonDown} onClick={isActive ? this.clearLinks : this.onLinkClick}>
+                        <div className={`documentLinksButton ${isActive ? `startLink` : ``}`} ref={this._linkButton}
+                            onPointerDown={isActive ? undefined : this.onLinkButtonDown} onClick={isActive ? this.clearLinks : this.onLinkClick}>
                             <FontAwesomeIcon className="documentdecorations-icon" icon="link" />
                         </div>
                         :
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 9d738180b..8570f6fff 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -663,7 +663,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
             }
             if (de.complete.annoDragData || this.rootDoc !== linkdrag.linkSourceDoc.context) {
                 const dropDoc = de.complete.annoDragData?.dropDocument ?? this._componentView?.getAnchor?.() ?? this.props.Document;
-                de.complete.linkDocument = DocUtils.MakeLink({ doc: linkdrag.linkSourceDoc }, { doc: dropDoc }, "link", undefined, undefined, undefined, [de.x, de.y]);
+                de.complete.linkDocument = DocUtils.MakeLink({ doc: linkdrag.linkSourceDoc }, { doc: dropDoc }, undefined, undefined, undefined, undefined, [de.x, de.y]);
             }
         }
     }
@@ -674,7 +674,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
         const portalLink = this.allLinks.find(d => d.anchor1 === this.props.Document);
         if (!portalLink) {
             const portal = Docs.Create.FreeformDocument([], { _width: NumCast(this.layoutDoc._width) + 10, _height: NumCast(this.layoutDoc._height), _fitWidth: true, title: StrCast(this.props.Document.title) + " [Portal]" });
-            DocUtils.MakeLink({ doc: this.props.Document }, { doc: portal }, "portal to");
+            DocUtils.MakeLink({ doc: this.props.Document }, { doc: portal }, "portal to:portal from");
         }
         this.Document.followLinkLocation = "inPlace";
         this.Document.followLinkZoom = true;
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index aadad5ffa..5982d4d66 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -152,7 +152,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
         croppingProto.isPrototype = true;
         croppingProto.proto = Cast(this.rootDoc.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO
         croppingProto.type = DocumentType.IMG;
-        croppingProto.layout = ImageBox.LayoutString("data")
+        croppingProto.layout = ImageBox.LayoutString("data");
         croppingProto.data = ObjectField.MakeCopy(this.rootDoc[this.fieldKey] as ObjectField);
         croppingProto["data-nativeWidth"] = anchw;
         croppingProto["data-nativeHeight"] = anchh;
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index b556b0ef1..668c6c8fc 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -160,11 +160,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
     public backPage = () => {
         this.Document._curPage = Math.max(1, (NumCast(this.Document._curPage) || 1) - 1);
         return true;
-    };
+    }
     public forwardPage = () => {
         this.Document._curPage = Math.min(NumCast(this.dataDoc[this.props.fieldKey + "-numPages"]), (NumCast(this.Document._curPage) || 1) + 1);
         return true;
-    };
+    }
     public gotoPage = (p: number) => this.Document._curPage = p;
 
     @undoBatch
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index 00c03875b..427e05edb 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -275,7 +275,7 @@ export class RichTextRules {
                                     this.TextBox.EditorView?.dispatch(rstate.tr.setSelection(new TextSelection(rstate.doc.resolve(start), rstate.doc.resolve(end - 3))));
                                 }
                                 const target = ((docx instanceof Doc) && docx) || Docs.Create.FreeformDocument([], { title: rawdocid.replace(/^:/, ""), _width: 500, _height: 500, }, docid);
-                                DocUtils.MakeLink({ doc: this.TextBox.getAnchor() }, { doc: target }, "portal to", undefined);
+                                DocUtils.MakeLink({ doc: this.TextBox.getAnchor() }, { doc: target }, "portal to:portal from", undefined);
 
                                 const fstate = this.TextBox.EditorView?.state;
                                 if (fstate && selection) {
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 5fe2a5ab1..9257cb75e 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -112,7 +112,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
         if (this.props.linkFrom) {
             const linkFrom = this.props.linkFrom();
             if (linkFrom) {
-                DocUtils.MakeLink({ doc: linkFrom }, { doc: linkTo }, "Link");
+                DocUtils.MakeLink({ doc: linkFrom }, { doc: linkTo });
             }
         }
     });
diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts
index 5e0cd67cc..83a2bc79b 100644
--- a/src/server/ApiManagers/UploadManager.ts
+++ b/src/server/ApiManagers/UploadManager.ts
@@ -14,7 +14,7 @@ import { normalize } from "path";
 import RouteSubscriber from "../RouteSubscriber";
 const imageDataUri = require('image-data-uri');
 import { SolrManager } from "./SearchManager";
-let fs = require('fs');
+const fs = require('fs');
 
 export enum Directory {
     parsed_files = "parsed_files",
@@ -265,7 +265,7 @@ export default class UploadManager extends ApiManager {
                 }
                 if (deleteFiles) {
                     const path = serverPathToFile(Directory.images, "");
-                    let regex = new RegExp(`${deleteFiles}.*`);
+                    const regex = new RegExp(`${deleteFiles}.*`);
                     fs.readdirSync(path).filter((f: any) => regex.test(f)).map((f: any) => fs.unlinkSync(path + f));
                 }
                 return imageDataUri.outputFile(uri, serverPathToFile(Directory.images, InjectSize(filename, origSuffix))).then((savedName: string) => {
-- 
cgit v1.2.3-70-g09d2


From c31bb0d5d8c4d42fb5cd97b1582de0cae1b16ca0 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 12 May 2022 12:17:12 -0400
Subject: fixed perfromance (flickering, speed) issues with having
 pointerEvents prop invalidate documents - switched to using a function to
 avoid flickering on PDFs of annotations in particular.

---
 src/Utils.ts                                       |  4 +++
 src/client/views/InkingStroke.tsx                  |  2 +-
 src/client/views/SidebarAnnos.tsx                  |  4 +--
 src/client/views/StyleProvider.tsx                 |  2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 14 +++++----
 src/client/views/nodes/ComparisonBox.tsx           |  4 +--
 src/client/views/nodes/DocumentView.tsx            |  4 +--
 src/client/views/nodes/FieldView.tsx               |  4 +--
 src/client/views/nodes/MapBox/MapBox.tsx           | 10 +++++--
 src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx |  4 +--
 src/client/views/nodes/PDFBox.tsx                  |  1 -
 src/client/views/nodes/WebBox.tsx                  | 12 ++++----
 src/client/views/pdf/Annotation.tsx                |  6 ++--
 src/client/views/pdf/PDFViewer.tsx                 | 34 ++++------------------
 14 files changed, 46 insertions(+), 59 deletions(-)

(limited to 'src/client/views/SidebarAnnos.tsx')

diff --git a/src/Utils.ts b/src/Utils.ts
index 205f9379e..c3c13a555 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -440,6 +440,10 @@ export function returnTrue() { return true; }
 
 export function returnFalse() { return false; }
 
+export function returnAll() { return "all"; }
+
+export function returnNone() { return "none"; }
+
 export function returnVal(val1?: number, val2?: number) { return val1 !== undefined ? val1 : val2 !== undefined ? val2 : 0; }
 
 export function returnOne() { return 1; }
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 5e9990444..3d9c048e5 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -332,7 +332,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
             inkStrokeWidth, inkStrokeWidth + (highlightIndex && closed && fillColor && (new Color(fillColor)).alpha() < 1 ? 6 : 15),
             StrCast(this.layoutDoc.strokeLineJoin), StrCast(this.layoutDoc.strokeLineCap),
             StrCast(this.layoutDoc.strokeBezier), !closed ? "none" : fillColor === "transparent" || suppressFill ? "none" : fillColor, startMarker, endMarker,
-            markerScale, undefined, inkScaleX, inkScaleY, "", this.props.pointerEvents ?? (this.props.layerProvider?.(this.props.Document) === false ? "none" : "visiblepainted"), 0.0,
+            markerScale, undefined, inkScaleX, inkScaleY, "", this.props.pointerEvents?.() ?? (this.props.layerProvider?.(this.props.Document) === false ? "none" : "visiblepainted"), 0.0,
             false, downHdlr);
         const fsize = +(StrCast(this.props.Document.fontSize, "12px").replace("px", ""));
         // bootsrap 3 style sheet sets line height to be 20px for default 14 point font size. 
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index 04c0565ea..9e939aa19 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -4,7 +4,7 @@ import { Doc, DocListCast, StrListCast, Opt } from "../../fields/Doc";
 import { Id } from '../../fields/FieldSymbols';
 import { List } from '../../fields/List';
 import { NumCast, StrCast } from '../../fields/Types';
-import { emptyFunction, OmitKeys, returnOne, returnTrue, returnZero } from '../../Utils';
+import { emptyFunction, OmitKeys, returnAll, returnOne, returnTrue, returnZero } from '../../Utils';
 import { Docs, DocUtils } from '../documents/Documents';
 import { Transform } from '../util/Transform';
 import { CollectionStackingView } from './collections/CollectionStackingView';
@@ -147,7 +147,7 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
                         renderDepth={this.props.renderDepth + 1}
                         viewType={CollectionViewType.Stacking}
                         fieldKey={this.sidebarKey}
-                        pointerEvents={"all"}
+                        pointerEvents={returnAll}
                     />
                 </div>
             </div>;
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index ca9826ab9..5056dedaf 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -204,7 +204,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
         }
         case StyleProp.PointerEvents:
             if (doc?.type === DocumentType.MARKER) return "none";
-            if (props?.pointerEvents === "none") return "none";
+            if (props?.pointerEvents?.() === "none") return "none";
             const layer = doc && props?.layerProvider?.(doc);
             const isInk = doc && StrCast(Doc.Layout(doc).layout).includes(InkingStroke.name);
             if (opacity() === 0 || (isInk && !docProps?.treeViewDoc) || doc?.isInkMask) return "none";
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 193750d8a..19b6612b0 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,5 +1,5 @@
 import { Bezier } from "bezier-js";
-import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
+import { action, computed, IReactionDisposer, observable, reaction, runInAction, trace } from "mobx";
 import { observer } from "mobx-react";
 import { computedFn } from "mobx-utils";
 import { DateField } from "../../../../fields/DateField";
@@ -1152,10 +1152,15 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
 
     isContentActive = () => this.props.isSelected() || this.props.isContentActive();
 
+    pointerEvents = () => {
+        const engine = this.props.layoutEngine?.() || StrCast(this.props.Document._layoutEngine);
+        const pointerEvents = this.props.isContentActive() === false ? "none" : this.backgroundActive || this.props.childPointerEvents ? "all" :
+            (this.props.viewDefDivClick || (engine === "pass" && !this.props.isSelected(true))) ? "none" : this.props.pointerEvents?.();
+        return pointerEvents;
+    }
     getChildDocView(entry: PoolData) {
         const childLayout = entry.pair.layout;
         const childData = entry.pair.data;
-        const engine = this.props.layoutEngine?.() || StrCast(this.props.Document._layoutEngine);
         return <CollectionFreeFormDocumentView key={childLayout[Id] + (entry.replica || "")}
             DataDoc={childData}
             Document={childLayout}
@@ -1197,8 +1202,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             bringToFront={this.bringToFront}
             showTitle={this.props.childShowTitle}
             dontRegisterView={this.props.dontRenderDocuments || this.props.dontRegisterView}
-            pointerEvents={this.props.isContentActive() === false ? "none" : this.backgroundActive || this.props.childPointerEvents ? "all" :
-                (this.props.viewDefDivClick || (engine === "pass" && !this.props.isSelected(true))) ? "none" : this.props.pointerEvents}
+            pointerEvents={this.pointerEvents}
             jitterRotation={this.props.styleProvider?.(childLayout, this.props, StyleProp.JitterRotation) || 0}
         //fitToBox={this.props.fitToBox || BoolCast(this.props.freezeChildDimensions)} // bcz: check this
         />;
@@ -1733,7 +1737,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             onContextMenu={this.onContextMenu}
             style={{
                 pointerEvents: this.props.Document.type === DocumentType.MARKER ? "none" :  // bcz: ugh.. this is here to prevent markers, which render as freeform views, from grabbing events -- need a better approach.
-                    this.backgroundEvents ? "all" : this.props.pointerEvents as any,
+                    this.backgroundEvents ? "all" : this.props.pointerEvents?.() as any,
                 transform: `scale(${this.contentScaling || 1})`,
                 width: `${100 / (this.contentScaling || 1)}%`,
                 height: this.isAnnotationOverlay && this.Document.scrollHeight ? NumCast(this.Document.scrollHeight) : `${100 / (this.contentScaling || 1)}%`// : this.isAnnotationOverlay ? (this.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight()
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index 78608b681..abb01c466 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -3,7 +3,7 @@ import { action, observable } from 'mobx';
 import { observer } from "mobx-react";
 import { Doc, Opt } from '../../../fields/Doc';
 import { Cast, NumCast, StrCast } from '../../../fields/Types';
-import { emptyFunction, OmitKeys, returnFalse, setupMoveUpEvents } from '../../../Utils';
+import { emptyFunction, OmitKeys, returnFalse, returnNone, setupMoveUpEvents } from '../../../Utils';
 import { DragManager } from '../../util/DragManager';
 import { SnappingManager } from '../../util/SnappingManager';
 import { undoBatch } from '../../util/UndoManager';
@@ -96,7 +96,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
                     Document={targetDoc}
                     DataDoc={undefined}
                     hideLinkButton={true}
-                    pointerEvents={"none"} />
+                    pointerEvents={returnNone} />
                 {clearButton(which)}
             </> :  // placeholder image if doc is missing
                 <div className="placeholder">
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 02ea87103..e117be0c2 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -148,7 +148,7 @@ export interface DocumentViewSharedProps {
     ignoreAutoHeight?: boolean;
     forceAutoHeight?: boolean;
     disableDocBrushing?: boolean; // should highlighting for this view be disabled when same document in another view is hovered over.
-    pointerEvents?: string;
+    pointerEvents?: () => Opt<string>;
     scriptContext?: any; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document
     createNewFilterDoc?: () => void;
     updateFilterDoc?: (doc: Doc) => void;
@@ -870,7 +870,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
 
         return <div className="documentView-contentsView"
             style={{
-                pointerEvents: this.props.pointerEvents as any ?? this.rootDoc.layoutKey === "layout_icon" ? "none" : (this.rootDoc.type !== DocumentType.INK && ((this.props.contentPointerEvents as any) || (this.isContentActive())) ? "all" : "none"),
+                pointerEvents: this.props.pointerEvents?.() as any ?? this.rootDoc.layoutKey === "layout_icon" ? "none" : (this.rootDoc.type !== DocumentType.INK && ((this.props.contentPointerEvents as any) || (this.isContentActive())) ? "all" : "none"),
                 height: this.headerMargin ? `calc(100% - ${this.headerMargin}px)` : undefined,
             }}>
             {!this._retryThumb || !this.thumbShown() ? (null) :
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index ae9acfe3f..686b4308b 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -2,7 +2,7 @@ import React = require("react");
 import { computed } from "mobx";
 import { observer } from "mobx-react";
 import { DateField } from "../../../fields/DateField";
-import { Doc, Field, FieldResult } from "../../../fields/Doc";
+import { Doc, Field, FieldResult, Opt } from "../../../fields/Doc";
 import { List } from "../../../fields/List";
 import { WebField } from "../../../fields/URLField";
 import { DocumentViewSharedProps } from "./DocumentView";
@@ -25,7 +25,7 @@ export interface FieldViewProps extends DocumentViewSharedProps {
     setHeight?: (height: number) => void;
 
     // properties intended to be used from within layout strings (otherwise use the function equivalents that work more efficiently with React)
-    pointerEvents?: string;
+    pointerEvents?: () => Opt<string>;
     fontSize?: number;
     height?: number;
     width?: number;
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index e7fc38ecd..c0fd8d8a0 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -489,13 +489,17 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         return this.addDocument(doc, annotationKey);
     }
 
+    pointerEvents = () => {
+        return this.props.isContentActive() && this.props.pointerEvents?.() !== "none" && !MarqueeOptionsMenu.Instance.isShown() ?
+            "all" :
+            SnappingManager.GetIsDragging() ?
+                undefined : "none";
+    }
     @computed get annotationLayer() {
-        const pe = this.props.isContentActive() && this.props.pointerEvents !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" :
-            SnappingManager.GetIsDragging() ? undefined : "none";
         return <div className="mapBox-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) || undefined }} ref={this._annotationLayer}>
             {this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno =>
                 <Annotation key={`${anno[Id]}-annotation`} {...this.props}
-                    fieldKey={this.annotationKey} pointerEvents={pe} showInfo={this.showInfo} dataDoc={this.dataDoc} anno={anno} />)}
+                    fieldKey={this.annotationKey} pointerEvents={this.pointerEvents} showInfo={this.showInfo} dataDoc={this.dataDoc} anno={anno} />)}
         </div>;
     }
 
diff --git a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
index 0d5fedb7b..db7dcb09d 100644
--- a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
+++ b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
@@ -4,7 +4,7 @@ import { observer } from "mobx-react";
 import * as React from "react";
 import { Doc } from '../../../../fields/Doc';
 import { Id } from '../../../../fields/FieldSymbols';
-import { emptyFunction, OmitKeys, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents } from '../../../../Utils';
+import { emptyFunction, OmitKeys, returnAll, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents } from '../../../../Utils';
 import { Docs } from '../../../documents/Documents';
 import { DocumentType } from '../../../documents/DocumentTypes';
 import { CollectionStackingView } from '../../collections/CollectionStackingView';
@@ -79,7 +79,7 @@ export class MapBoxInfoWindow extends React.Component<MapBoxInfoWindowProps & Vi
                         addDocument={(doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((p, d) => p && Doc.AddDocToList(this.props.place, "data", d), true as boolean)}
                         renderDepth={this.props.renderDepth + 1}
                         viewType={CollectionViewType.Stacking}
-                        pointerEvents="all"
+                        pointerEvents={returnAll}
                     />
                 </div>
                 <hr />
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index e6e723ef1..35b5e78a8 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -416,7 +416,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                     moveDocument={this.moveDocument}
                     removeDocument={this.removeDocument}
                     whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
-                    startupLive={true}
                     crop={this.crop}
                     ContentScaling={returnOne}
                 />
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index f441e5d36..f01dba4d0 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -12,10 +12,9 @@ import { ComputedField } from "../../../fields/ScriptField";
 import { Cast, ImageCast, NumCast, StrCast } from "../../../fields/Types";
 import { ImageField, WebField } from "../../../fields/URLField";
 import { TraceMobx } from "../../../fields/util";
-import { emptyFunction, getWordAtPoint, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, smoothScroll, StopEvent, Utils } from "../../../Utils";
+import { emptyFunction, getWordAtPoint, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, smoothScroll, Utils } from "../../../Utils";
 import { Docs } from "../../documents/Documents";
 import { CurrentUserUtils } from "../../util/CurrentUserUtils";
-import { KeyCodes } from "../../util/KeyCodes";
 import { ScriptingGlobals } from "../../util/ScriptingGlobals";
 import { SnappingManager } from "../../util/SnappingManager";
 import { undoBatch } from "../../util/UndoManager";
@@ -648,7 +647,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
             (NumCast(this.layoutDoc.nativeWidth) - Doc.NativeWidth(this.dataDoc)) * this.props.PanelWidth() / NumCast(this.layoutDoc.nativeWidth))
 
     @computed get content() {
-        const interactive = !this.props.docViewPath().lastElement()?.docView?._pendingDoubleClick && this.props.isContentActive() && this.props.pointerEvents !== "none" && CurrentUserUtils.SelectedTool === InkTool.None && !DocumentDecorations.Instance?.Interacting;
+        const interactive = !this.props.docViewPath().lastElement()?.docView?._pendingDoubleClick && this.props.isContentActive() && this.props.pointerEvents?.() !== "none" && CurrentUserUtils.SelectedTool === InkTool.None && !DocumentDecorations.Instance?.Interacting;
         return <div className={"webBox-cont" + (interactive ? "-interactive" : "")}
             onKeyDown={e => e.stopPropagation()}
             style={{ width: !this.layoutDoc.forceReflow ? NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]) || `100%` : "100%", }}>
@@ -658,10 +657,9 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
 
     @computed get annotationLayer() {
         TraceMobx();
-        const pe = this.pointerEvents();
         return <div className="webBox-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) || undefined }} ref={this._annotationLayer}>
             {this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno =>
-                <Annotation {...this.props} fieldKey={this.annotationKey} pointerEvents={pe} showInfo={this.showInfo} dataDoc={this.dataDoc} anno={anno} key={`${anno[Id]}-annotation`} />)}
+                <Annotation {...this.props} fieldKey={this.annotationKey} pointerEvents={this.pointerEvents} showInfo={this.showInfo} dataDoc={this.dataDoc} anno={anno} key={`${anno[Id]}-annotation`} />)}
         </div>;
 
     }
@@ -703,9 +701,9 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         }
         return this.props.styleProvider?.(doc, props, property);
     }
-    pointerEvents = () => !this._draggingSidebar && this.props.isContentActive() && this.props.pointerEvents !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" : SnappingManager.GetIsDragging() ? undefined : "none";
+    pointerEvents = () => !this._draggingSidebar && this.props.isContentActive() && this.props.pointerEvents?.() !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" : SnappingManager.GetIsDragging() ? undefined : "none";
     render() {
-        const pointerEvents = this.props.layerProvider?.(this.layoutDoc) === false ? "none" : this.props.pointerEvents ? this.props.pointerEvents as any : undefined;
+        const pointerEvents = this.props.layerProvider?.(this.layoutDoc) === false ? "none" : this.props.pointerEvents?.() as any;
         const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1;
         const scale = previewScale * (this.props.scaling?.() || 1);
         const renderAnnotations = (docFilters?: () => string[]) =>
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index b1d1d8293..218f37f3d 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -16,7 +16,7 @@ interface IAnnotationProps extends FieldViewProps {
     dataDoc: Doc;
     fieldKey: string;
     showInfo: (anno: Opt<Doc>) => void;
-    pointerEvents?: string;
+    pointerEvents?: () => Opt<string>;
 }
 @observer
 export
@@ -28,7 +28,7 @@ export
 
 interface IRegionAnnotationProps extends IAnnotationProps {
     document: Doc;
-    pointerEvents?: string;
+    pointerEvents?: () => Opt<string>;
 }
 @observer
 class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
@@ -98,7 +98,7 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
                 width: NumCast(this.props.document._width),
                 height: NumCast(this.props.document._height),
                 opacity: this._brushed ? 0.5 : undefined,
-                pointerEvents: this.props.pointerEvents as any,
+                pointerEvents: this.props.pointerEvents?.() as any,
                 backgroundColor: this._brushed ? "orange" : StrCast(this.props.document.backgroundColor),
             }} >
         </div>);
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 7ad452e54..608ba07ff 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -8,7 +8,7 @@ import { InkTool } from "../../../fields/InkField";
 import { Cast, NumCast, StrCast } from "../../../fields/Types";
 import { PdfField } from "../../../fields/URLField";
 import { TraceMobx } from "../../../fields/util";
-import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, OmitKeys, smoothScroll, Utils } from "../../../Utils";
+import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, OmitKeys, returnFalse, smoothScroll, Utils } from "../../../Utils";
 import { DocUtils } from "../../documents/Documents";
 import { CurrentUserUtils } from "../../util/CurrentUserUtils";
 import { SelectionManager } from "../../util/SelectionManager";
@@ -41,7 +41,6 @@ interface IViewerProps extends FieldViewProps {
     fieldKey: string;
     pdf: Pdfjs.PDFDocumentProxy;
     url: string;
-    startupLive: boolean;
     loaded?: (nw: number, nh: number, np: number) => void;
     setPdfViewer: (view: PDFViewer) => void;
     ContentScaling?: () => number;
@@ -89,28 +88,8 @@ export class PDFViewer extends React.Component<IViewerProps> {
     @computed get inlineTextAnnotations() { return this.allAnnotations.filter(a => a.textInlineAnnotations); }
 
     componentDidMount = async () => {
-        // change the address to be the file address of the PNG version of each page
-        // file address of the pdf
-        const { url: { href } } = Cast(this.props.dataDoc[this.props.fieldKey], PdfField)!;
-        const { url: relative } = this.props;
-        if (relative.includes("/pdfs/")) {
-            const pathComponents = relative.split("/pdfs/")[1].split("/");
-            const coreFilename = pathComponents.pop()!.split(".")[0];
-            const params: any = {
-                coreFilename,
-                pageNum: Math.min(this.props.pdf.numPages, Math.max(1, NumCast(this.props.Document._curPage, 1))),
-            };
-            if (pathComponents.length) {
-                params.subtree = `${pathComponents.join("/")}/`;
-            }
-        } else {
-            const params: any = {
-                coreFilename: relative.split("/")[relative.split("/").length - 1],
-                pageNum: Math.min(this.props.pdf.numPages, Math.max(1, NumCast(this.props.Document._curPage, 1))),
-            };
-        }
         runInAction(() => this._showWaiting = true);
-        this.props.startupLive && this.setupPdfJsViewer();
+        this.setupPdfJsViewer();
         this._mainCont.current?.addEventListener("scroll", e => (e.target as any).scrollLeft = 0);
 
         this._disposers.autoHeight = reaction(() => this.props.layoutDoc._autoHeight,
@@ -456,12 +435,11 @@ export class PDFViewer extends React.Component<IViewerProps> {
         }
     }
 
-    pointerEvents = () => this.props.isContentActive() && this.props.pointerEvents !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" : SnappingManager.GetIsDragging() ? undefined : "none";
+    pointerEvents = () => this.props.isContentActive() && this.props.pointerEvents?.() !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" : SnappingManager.GetIsDragging() ? undefined : "none";
     @computed get annotationLayer() {
-        const pe = this.pointerEvents();
         return <div className="pdfViewerDash-annotationLayer" style={{ height: Doc.NativeHeight(this.props.Document), transform: `scale(${this._zoomed})` }} ref={this._annotationLayer}>
             {this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno =>
-                <Annotation {...this.props} fieldKey={this.props.fieldKey + "-annotations"} pointerEvents={pe} showInfo={this.showInfo} dataDoc={this.props.dataDoc} anno={anno} key={`${anno[Id]}-annotation`} />)}
+                <Annotation {...this.props} fieldKey={this.props.fieldKey + "-annotations"} pointerEvents={this.pointerEvents} showInfo={this.showInfo} dataDoc={this.props.dataDoc} anno={anno} key={`${anno[Id]}-annotation`} />)}
         </div>;
     }
 
@@ -536,7 +514,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
         </div>;
     }
     @computed get pdfViewerDiv() {
-        return <div className={"pdfViewerDash-text" + (this.props.pointerEvents !== "none" && this._textSelecting && this.props.isContentActive() ? "-selected" : "")} ref={this._viewer} />;
+        return <div className={"pdfViewerDash-text" + (this.props.pointerEvents?.() !== "none" && this._textSelecting && this.props.isContentActive() ? "-selected" : "")} ref={this._viewer} />;
     }
     @computed get contentScaling() { return this.props.ContentScaling?.() || 1; }
     contentZoom = () => this._zoomed;
@@ -544,7 +522,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
     render() {
         TraceMobx();
         return <div className="pdfViewer-content">
-            <div className={`pdfViewerDash${this.props.isContentActive() && this.props.pointerEvents !== "none" ? "-interactive" : ""}`} ref={this._mainCont}
+            <div className={`pdfViewerDash${this.props.isContentActive() && this.props.pointerEvents?.() !== "none" ? "-interactive" : ""}`} ref={this._mainCont}
                 onScroll={this.onScroll} onWheel={this.onZoomWheel} onPointerDown={this.onPointerDown} onClick={this.onClick}
                 style={{
                     overflowX: this._zoomed !== 1 ? "scroll" : undefined,
-- 
cgit v1.2.3-70-g09d2

