From 223262242f7db021c8449e920645892cc5ed2820 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sat, 17 Oct 2020 17:45:10 -0400
Subject: major rewrite of native width/height/aspect.  Fixed scaling of text
 note sidebars.

---
 .../views/nodes/formattedText/FormattedTextBox.tsx      | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

(limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx')

diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 903bbaaa3..d44f35a96 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -663,7 +663,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         const optionItems = options && "subitems" in options ? options.subitems : [];
         !Doc.UserDoc().noviceMode && optionItems.push({ description: !this.Document._singleLine ? "Make Single Line" : "Make Multi Line", event: () => this.layoutDoc._singleLine = !this.layoutDoc._singleLine, icon: "expand-arrows-alt" });
         optionItems.push({ description: `${this.Document._autoHeight ? "Lock" : "Auto"} Height`, event: () => this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight, icon: "plus" });
-        optionItems.push({ description: `${!this.layoutDoc._nativeWidth || !this.layoutDoc._nativeHeight ? "Lock" : "Unlock"} Aspect`, event: this.toggleNativeDimensions, icon: "snowflake" });
+        optionItems.push({ description: `${!Doc.NativeWidth(this.layoutDoc) || !Doc.NativeHeight(this.layoutDoc) ? "Lock" : "Unlock"} Aspect`, event: this.toggleNativeDimensions, icon: "snowflake" });
         !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "eye" });
         this._downX = this._downY = Number.NaN;
     }
@@ -1454,10 +1454,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
 
     public endUndoTypingBatch() {
         const wasUndoing = this._undoTyping;
-        if (this._undoTyping) {
-            this._undoTyping.end();
-            this._undoTyping = undefined;
-        }
+        this._undoTyping?.end();
+        this._undoTyping = undefined;
         return wasUndoing;
     }
     public static LiveTextUndo: UndoManager.Batch | undefined;
@@ -1470,8 +1468,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
 
         FormattedTextBox.LiveTextUndo?.end();
         FormattedTextBox.LiveTextUndo = undefined;
-        // move the richtextmenu offscreen
-        //if (!RichTextMenu.Instance.Pinned) RichTextMenu.Instance.delayHide();
     }
 
     _lastTimedMark: Mark | undefined = undefined;
@@ -1574,10 +1570,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             />;
     }
 
+    sidebarContentScaling = () => this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1);
     @computed get sidebarCollection() {
         const fitToBox = this.props.Document._fitToBox;
         const collectionProps = {
             ...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit,
+            NativeWidth: returnZero,
+            NativeHeight: returnZero,
             PanelHeight: this.props.PanelHeight,
             PanelWidth: this.sidebarWidth,
             xMargin: 0,
@@ -1591,7 +1590,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             isSelected: this.props.isSelected,
             select: emptyFunction,
             active: this.annotationsActive,
-            ContentScaling: returnOne,
+            ContentScaling: this.sidebarContentScaling,
             whenActiveChanged: this.whenActiveChanged,
             removeDocument: this.removeDocument,
             moveDocument: this.moveDocument,
@@ -1626,7 +1625,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         const padding = Math.max(margins + ((selected && !this.layoutDoc._singleLine) || minimal ? -selPad : 0), 0);
         const selclass = selected && !this.layoutDoc._singleLine && margins >= 10 ? "-selected" : "";
         return (
-            <div className={"formattedTextBox-cont"} ref={this._boxRef}
+            <div className="formattedTextBox-cont" ref={this._boxRef}
                 style={{
                     transform: `scale(${scale})`,
                     transformOrigin: "top left",
-- 
cgit v1.2.3-70-g09d2


From c57cb369f8bd15a274e0a399d84a7f894fa11161 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 30 Oct 2020 11:35:56 -0400
Subject: fixed setting links from link dialogue in text boxes

---
 src/client/views/nodes/formattedText/FormattedTextBox.tsx | 6 +++---
 src/client/views/nodes/formattedText/RichTextMenu.tsx     | 8 ++++++--
 src/fields/Doc.ts                                         | 4 +++-
 3 files changed, 12 insertions(+), 6 deletions(-)

(limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx')

diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index d44f35a96..bc9e8e99d 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -11,7 +11,7 @@ import { EditorState, NodeSelection, Plugin, TextSelection, Transaction } from "
 import { ReplaceStep } from 'prosemirror-transform';
 import { EditorView } from "prosemirror-view";
 import { DateField } from '../../../../fields/DateField';
-import { DataSym, Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym, AclEdit, AclAdmin, UpdatingFromServer } from "../../../../fields/Doc";
+import { DataSym, Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym, AclEdit, AclAdmin, UpdatingFromServer, ForceServerWrite } from "../../../../fields/Doc";
 import { documentSchema } from '../../../../fields/documentSchemas';
 import applyDevTools = require("prosemirror-dev-tools");
 import { removeMarkWithAttrs } from "./prosemirrorPatches";
@@ -805,9 +805,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                     tr = tr.addMark(pos, pos + node.nodeSize, link);
                 }
             });
-            this.dataDoc[UpdatingFromServer] = true;  // need to allow permissions for adding links to readonly/augment only documents
+            this.dataDoc[ForceServerWrite] = this.dataDoc[UpdatingFromServer] = true;  // need to allow permissions for adding links to readonly/augment only documents
             this._editorView!.dispatch(tr.removeMark(sel.from, sel.to, splitter));
-            this.dataDoc[UpdatingFromServer] = false;
+            this.dataDoc[UpdatingFromServer] = this.dataDoc[ForceServerWrite] = false;
         }
     }
     componentDidMount() {
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 2700c508b..cf9b03308 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -31,6 +31,7 @@ const { toggleMark } = require("prosemirror-commands");
 export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
     static Instance: RichTextMenu;
     public overMenu: boolean = false; // kind of hacky way to prevent selects not being selectable
+    private _linkToRef = React.createRef<HTMLInputElement>();
 
     @observable public view?: EditorView;
     public editorProps: FieldViewProps & FormattedTextBoxProps | undefined;
@@ -154,6 +155,9 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
 
     @action
     public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: any) {
+        if (this._linkToRef.current?.getBoundingClientRect().width) {
+            return;
+        }
         this.view = view;
         if (!view || !view.hasFocus()) {
             return;
@@ -792,7 +796,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
         const self = this;
 
         function onLinkChange(e: React.ChangeEvent<HTMLInputElement>) {
-            self.TextView.endUndoTypingBatch();
+            self.TextView?.endUndoTypingBatch();
             UndoManager.RunInBatch(() => self.setCurrentLink(e.target.value), "link change");
         }
 
@@ -807,7 +811,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
         const dropdownContent =
             <div className="dropdown link-menu">
                 <p>Linked to:</p>
-                <input value={link} placeholder="Enter URL" onChange={onLinkChange} />
+                <input value={link} ref={this._linkToRef} placeholder="Enter URL" onChange={onLinkChange} />
                 <button className="make-button" onPointerDown={e => this.makeLinkToURL(link, "add:right")}>Apply hyperlink</button>
                 <div className="divider"></div>
                 <button className="remove-button" onPointerDown={e => this.deleteLink()}>Remove link</button>
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index adda40621..c43ec5622 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -92,6 +92,7 @@ export const AclAddonly = Symbol("AclAddonly");
 export const AclEdit = Symbol("AclEdit");
 export const AclAdmin = Symbol("AclAdmin");
 export const UpdatingFromServer = Symbol("UpdatingFromServer");
+export const ForceServerWrite = Symbol("ForceServerWrite");
 export const CachedUpdates = Symbol("Cached updates");
 
 const AclMap = new Map<string, symbol>([
@@ -185,9 +186,10 @@ export class Doc extends RefField {
     @observable public [AclSym]: { [key: string]: symbol };
 
     private [UpdatingFromServer]: boolean = false;
+    private [ForceServerWrite]: boolean = false;
 
     private [Update] = (diff: any) => {
-        !this[UpdatingFromServer] && DocServer.UpdateField(this[Id], diff);
+        (!this[UpdatingFromServer] || this[ForceServerWrite]) && DocServer.UpdateField(this[Id], diff);
     }
 
     private [Self] = this;
-- 
cgit v1.2.3-70-g09d2


From 83d3756537cfcd8a2248c4b8a2a6f75f77154602 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 9 Nov 2020 21:40:59 -0500
Subject: fixed autoHeight for formattedTextSidebars when the text document has
 been scaled.  cleaned up link groups.  fixed pushpins that don't focus on
 target (e.g., a si m ple pushpin on a PDF).

---
 src/client/util/LinkManager.ts                     |  9 +----
 .../views/collections/CollectionStackingView.tsx   | 10 +++--
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  3 +-
 src/client/views/linking/LinkMenu.tsx              | 29 ++++++---------
 src/client/views/linking/LinkMenuGroup.tsx         | 43 +++-------------------
 src/client/views/nodes/LinkDocPreview.tsx          | 17 ++++-----
 .../views/nodes/formattedText/FormattedTextBox.tsx | 20 +++++-----
 7 files changed, 42 insertions(+), 89 deletions(-)

(limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx')

diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index 3a0c0e3eb..802b8ae7b 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -35,7 +35,7 @@ export class LinkManager {
 
     allLinks = computedFn(function allLinks(this: any): Doc[] {
         const lset = new Set<Doc>(DocListCast(Doc.LinkDBDoc().data));
-        SharingManager.Instance.users.forEach(user => DocListCast(user.linkDatabase?.data).map(doc => lset.add(doc)));
+        SharingManager.Instance.users.forEach(user => DocListCast(user.linkDatabase?.data).forEach(doc => lset.add(doc)));
         return Array.from(lset);
     }, true);
 
@@ -69,13 +69,6 @@ export class LinkManager {
         return anchorGroups;
     }
 
-    // returns a list of all metadata docs associated with the given group type
-    public getAllMetadataDocsInGroup(groupType: string): Array<Doc> {
-        const md: Doc[] = [];
-        LinkManager.Instance.allLinks().forEach(linkDoc => StrCast(linkDoc.linkRelationship).toUpperCase() === groupType.toUpperCase() && md.push(linkDoc));
-        return md;
-    }
-
     // checks if a link with the given anchors exists
     public doesLinkExist(anchor1: Doc, anchor2: Doc): boolean {
         return -1 !== LinkManager.Instance.allLinks().findIndex(linkDoc =>
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 62f733058..97eacaeab 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -352,8 +352,12 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
                     const doc = this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc;
                     this.observer = new _global.ResizeObserver(action((entries: any) => {
                         if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) {
-                            const height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", "")))));
-                            Doc.Layout(doc)._height = Math.max(height, NumCast(doc[this.props.fieldKey + "-height"]));
+                            const height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), Math.max(...this.refList.map(r => NumCast(Doc.Layout(doc)._viewScale, 1) * Number(getComputedStyle(r).height.replace("px", "")))));
+                            if (this.props.annotationsKey) {
+                                doc[this.props.annotationsKey + "-height"] = height;
+                            } else {
+                                Doc.Layout(doc)._height = height * NumCast(Doc.Layout(doc)._viewScale, 1);
+                            }
                         }
                     }));
                     this.observer.observe(ref);
@@ -406,7 +410,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
                     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);
-                            Doc.Layout(doc)._height = Math.max(height, NumCast(doc[this.props.fieldKey + "-height"]));
+                            Doc.Layout(doc)._height = Math.max(height * NumCast(doc[this.props.fieldKey + "-height"]), NumCast(doc[this.props.fieldKey + "-height"]));
                         }
                     }));
                     this.observer.observe(ref);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 4541716f3..21e653e02 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -926,8 +926,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                     afterFocus && setTimeout(afterFocus, delay);
                 } else {
                     !dontCenter && delay && this.props.focus(this.props.Document);
-                    // @ts-ignore
-                    afterFocus(true);
+                    afterFocus?.(!dontCenter && delay ? true : false);
 
                 }
             }
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index 3b4912d3d..54b597f59 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -59,24 +59,17 @@ export class LinkMenu extends React.Component<Props> {
     }
 
     renderAllGroups = (groups: Map<string, Array<Doc>>): Array<JSX.Element> => {
-        const linkItems: Array<JSX.Element> = [];
-        groups.forEach((group, groupType) => {
-            linkItems.push(
-                <LinkMenuGroup
-                    key={groupType}
-                    docView={this.props.docView}
-                    sourceDoc={this.props.docView.props.Document}
-                    group={group}
-                    groupType={groupType}
-                    showEditor={action((linkDoc: Doc) => this._editingLink = linkDoc)}
-                    addDocTab={this.props.addDocTab} />
-            );
-        });
-
-        // if source doc has no links push message
-        if (linkItems.length === 0) linkItems.push(<p key="">No links have been created yet. Drag the linking button onto another document to create a link.</p>);
-
-        return linkItems;
+        const linkItems = Array.from(groups.entries()).map(group =>
+            <LinkMenuGroup
+                key={group[0]}
+                docView={this.props.docView}
+                sourceDoc={this.props.docView.props.Document}
+                group={group[1]}
+                groupType={group[0]}
+                showEditor={action(linkDoc => this._editingLink = linkDoc)}
+                addDocTab={this.props.addDocTab} />);
+
+        return linkItems.length ? linkItems : [<p key="">No links have been created yet. Drag the linking button onto another document to create a link.</p>];
     }
 
     @computed
diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx
index e76227ccf..e53655fd3 100644
--- a/src/client/views/linking/LinkMenuGroup.tsx
+++ b/src/client/views/linking/LinkMenuGroup.tsx
@@ -1,17 +1,12 @@
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action } from "mobx";
 import { observer } from "mobx-react";
 import { Doc } from "../../../fields/Doc";
 import { Id } from "../../../fields/FieldSymbols";
-import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
-import { Docs } from "../../documents/Documents";
-import { DragManager, SetupDrag } from "../../util/DragManager";
+import { Cast } from "../../../fields/Types";
 import { LinkManager } from "../../util/LinkManager";
 import { DocumentView } from "../nodes/DocumentView";
 import './LinkMenu.scss';
-import { LinkMenuItem, StartLinkTargetsDrag } from "./LinkMenuItem";
+import { LinkMenuItem } from "./LinkMenuItem";
 import React = require("react");
-import { Cast } from "../../../fields/Types";
 
 interface LinkMenuGroupProps {
     sourceDoc: Doc;
@@ -26,34 +21,8 @@ interface LinkMenuGroupProps {
 export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
 
     private _drag = React.createRef<HTMLDivElement>();
-    private _table = React.createRef<HTMLDivElement>();
     private _menuRef = React.createRef<HTMLDivElement>();
 
-    onLinkButtonDown = (e: React.PointerEvent): void => {
-        e.stopPropagation();
-        document.removeEventListener("pointermove", this.onLinkButtonMoved);
-        document.addEventListener("pointermove", this.onLinkButtonMoved);
-        document.removeEventListener("pointerup", this.onLinkButtonUp);
-        document.addEventListener("pointerup", this.onLinkButtonUp);
-    }
-
-    onLinkButtonUp = (e: PointerEvent): void => {
-        document.removeEventListener("pointermove", this.onLinkButtonMoved);
-        document.removeEventListener("pointerup", this.onLinkButtonUp);
-        e.stopPropagation();
-    }
-
-    onLinkButtonMoved = async (e: PointerEvent) => {
-        if (this._drag.current && (e.movementX > 1 || e.movementY > 1)) {
-            document.removeEventListener("pointermove", this.onLinkButtonMoved);
-            document.removeEventListener("pointerup", this.onLinkButtonUp);
-
-            const targets = this.props.group.map(l => LinkManager.getOppositeAnchor(l, this.props.sourceDoc)).filter(d => d) as Doc[];
-            StartLinkTargetsDrag(this._drag.current, this.props.docView, e.x, e.y, this.props.sourceDoc, targets);
-        }
-        e.stopPropagation();
-    }
-
     render() {
         const set = new Set<Doc>(this.props.group);
         const groupItems = Array.from(set.keys()).map(linkDoc => {
@@ -75,11 +44,9 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
         return (
             <div className="linkMenu-group" ref={this._menuRef}>
 
-                {/* <div className="linkMenu-group-name">
-                    <p ref={this._drag} onPointerDown={this.onLinkButtonDown}
-                        className={this.props.groupType === "*" || this.props.groupType === "" ? "" : "expand-one"} > {this.props.groupType}:</p>
-                    {this.props.groupType === "*" || this.props.groupType === "" ? <></> : this.viewGroupAsTable(this.props.groupType)}
-                </div> */}
+                <div className="linkMenu-group-name">
+                    <p ref={this._drag} className={this.props.groupType === "*" || this.props.groupType === "" ? "" : "expand-one"} > {this.props.groupType}:</p>
+                </div>
 
                 <div className="linkMenu-group-wrapper">
                     {groupItems}
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 867be9735..d47942bd9 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -77,19 +77,16 @@ export class LinkDocPreview extends React.Component<Props> {
             this.props.addDocTab(Docs.Create.WebDocument(this.props.href, { _fitWidth: true, title: this.props.href, _width: 200, _height: 400, useCors: true }), "add:right");
         }
     }
-    width = () => Math.min(225, NumCast(this._targetDoc?.[WidthSym](), 225)) - 16;
-    height = () => Math.min(225, NumCast(this._targetDoc?.[HeightSym](), 225)) - 16;
+    width = () => Math.min(225, NumCast(this._targetDoc?.[WidthSym](), 225));
+    height = () => Math.min(225, NumCast(this._targetDoc?.[HeightSym](), 225));
     @computed get targetDocView() {
         return !this._targetDoc ?
-            <div style={{
-                pointerEvents: "all", maxWidth: 225, maxHeight: 225, width: "100%", height: "100%",
-                overflow: "hidden"
-            }}>
+            <div style={{ pointerEvents: "all", maxWidth: 225, maxHeight: 225, width: "100%", height: "100%", overflow: "hidden" }}>
                 <div style={{ width: "100%", height: "100%", textOverflow: "ellipsis", }} onPointerDown={this.pointerDown}>
                     {this._toolTipText}
                 </div>
-            </div> :
-
+            </div>
+            :
             <ContentFittingDocumentView
                 Document={this._targetDoc}
                 LibraryPath={emptyPath}
@@ -109,8 +106,8 @@ export class LinkDocPreview extends React.Component<Props> {
                 ContainingCollectionDoc={undefined}
                 ContainingCollectionView={undefined}
                 renderDepth={-1}
-                PanelWidth={this.width} //Math.min(350, NumCast(target._width, 350))}
-                PanelHeight={this.height} //Math.min(250, NumCast(target._height, 250))}
+                PanelWidth={this.width}
+                PanelHeight={this.height}
                 focus={emptyFunction}
                 whenActiveChanged={returnFalse}
                 bringToFront={returnFalse}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index bc9e8e99d..fe38939c5 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -812,6 +812,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     }
     componentDidMount() {
         this._cachedLinks = DocListCast(this.Document.links);
+        this._disposers.sidebarheight = reaction(
+            () => ({ annoHeight: NumCast(this.rootDoc[this.annotationKey + "-height"]), textHeight: NumCast(this.rootDoc[this.fieldKey + "-height"]) }),
+            ({ annoHeight, textHeight }) => {
+                this.layoutDoc._autoHeight && (this.rootDoc._height = Math.max(annoHeight, textHeight));
+            });
         this._disposers.links = reaction(() => DocListCast(this.Document.links), // if a link is deleted, then remove all hyperlinks that reference it from the text's marks
             newLinks => {
                 this._cachedLinks.forEach(l => !newLinks.includes(l) && this.RemoveLinkFromDoc(l));
@@ -1540,18 +1545,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 }, 10);
             } else {
                 try {
-                    const boxHeight = Number(getComputedStyle(this._boxRef.current!).height.replace("px", ""));
+                    const boxHeight = Number(getComputedStyle(this._boxRef.current!).height.replace("px", "")) * NumCast(this.Document._viewScale, 1);
                     const outer = this.rootDoc[HeightSym]() - boxHeight - (this.props.ChromeHeight ? this.props.ChromeHeight() : 0);
-                    const finalHeight = newHeight + Math.max(0, outer);
-                    const maxsidebar = !this.sidebarWidth() ? 0 : Array.from(this._boxRef.current!.getElementsByClassName("collectionStackingViewFieldColumn")).reduce((prev, ele) => Math.max(prev, Number(getComputedStyle(ele).height.replace("px", ""))), 0);
-                    if (this.rootDoc._height !== finalHeight && finalHeight > maxsidebar) {
-                        this.rootDoc._height = finalHeight;
-                        this.layoutDoc._nativeHeight = nh ? scrollHeight : undefined;
-                    }
-                    this.rootDoc[this.fieldKey + "-height"] = finalHeight;
+                    this.rootDoc[this.fieldKey + "-height"] = newHeight + Math.max(0, outer);
                 } catch (e) { console.log("Error in tryUpdateHeight"); }
             }
-        } else this.rootDoc[this.fieldKey + "-height"] = 0;
+        } //else this.rootDoc[this.fieldKey + "-height"] = 0;
     }
 
     @computed get audioHandle() {
@@ -1609,7 +1608,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
 
     @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); }
     sidebarWidth = () => Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth();
-    sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()) / this.props.ContentScaling(), 0);
+    sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()) / this.props.ContentScaling(), 0).scale(1 / NumCast(this.layoutDoc._viewScale, 1));
     @computed get sidebarColor() { return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "#e4e4e4")); }
     render() {
         TraceMobx();
@@ -1631,6 +1630,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                     transformOrigin: "top left",
                     width: `${100 / scale}%`,
                     height: `calc(${100 / scale}% - ${this.props.ChromeHeight?.() || 0}px)`,
+                    overflowY: this.layoutDoc._autoHeight ? "hidden" : undefined,
                     ...this.styleFromLayoutString(scale)   // this converts any expressions in the format string to style props.  e.g., <FormattedTextBox height='{this._headerHeight}px' >
                 }}>
                 <div className={`formattedTextBox-cont`} ref={this._ref}
-- 
cgit v1.2.3-70-g09d2

