From ecaf1da499b41d0f873c64cb128118a6a291229e Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 15 Mar 2021 23:42:19 -0400
Subject: fixed warnings.  made savedAnnotations an ObservableMap. turned off
 annotationLayer when there are no annotations - text is blurry on windows
 Chrome with mix-blend-mode overlay

---
 src/client/views/nodes/ImageBox.tsx | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

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

diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index bc01acdfd..0be0b5f30 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -1,4 +1,4 @@
-import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, reaction, runInAction, ObservableMap } from 'mobx';
 import { observer } from "mobx-react";
 import { Dictionary } from 'typescript-collections';
 import { DataSym, Doc, DocListCast, WidthSym } from '../../../fields/Doc';
@@ -63,7 +63,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
     componentDidMount() {
         this._disposers.selection = reaction(() => this.props.isSelected(),
             selected => !selected && setTimeout(() => {
-                this._savedAnnotations.values().forEach(v => v.forEach(a => a.remove()));
+                Array.from(this._savedAnnotations.values()).forEach(v => v.forEach(a => a.remove()));
                 this._savedAnnotations.clear();
             }));
         this._disposers.path = reaction(() => ({ nativeSize: this.nativeSize, width: this.layoutDoc[WidthSym]() }),
@@ -337,7 +337,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
     private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
     private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
     @observable _marqueeing: number[] | undefined;
-    @observable _savedAnnotations: Dictionary<number, HTMLDivElement[]> = new Dictionary<number, HTMLDivElement[]>();
+    @observable _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
     @computed get annotationLayer() {
         return <div className="imageBox-annotationLayer" style={{ height: this.props.PanelHeight() }} ref={this._annotationLayer} />;
     }
@@ -388,7 +388,17 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
             </CollectionFreeFormView>
             {this.annotationLayer}
             {!this._marqueeing || !this._mainCont.current || !this._annotationLayer.current ? (null) :
-                <MarqueeAnnotator rootDoc={this.rootDoc} scrollTop={0} down={this._marqueeing} scaling={this.props.scaling} addDocument={this.addDocument} finishMarquee={this.finishMarquee} savedAnnotations={this._savedAnnotations} annotationLayer={this._annotationLayer.current} mainCont={this._mainCont.current} />}
+                <MarqueeAnnotator rootDoc={this.rootDoc}
+                    scrollTop={0} down={this._marqueeing}
+                    scaling={this.props.scaling}
+                    docView={this.props.docViewPath().lastElement()}
+                    addDocument={this.addDocument}
+                    finishMarquee={this.finishMarquee}
+                    savedAnnotations={this._savedAnnotations}
+                    annotationLayer={this._annotationLayer.current}
+                    mainCont={this._mainCont.current}
+                />}
         </div >);
     }
+
 }
-- 
cgit v1.2.3-70-g09d2


From 4e47c8020f85018973b67d929066b109f5db8a75 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 16 Mar 2021 15:50:54 -0400
Subject: put invalidation of imagebox's suffix on a 1sec delay for efficiency.

---
 src/client/views/nodes/FontIconBox.tsx             |  2 +-
 src/client/views/nodes/ImageBox.tsx                | 68 +++++++---------------
 .../views/nodes/formattedText/FormattedTextBox.tsx |  3 +-
 3 files changed, 25 insertions(+), 48 deletions(-)

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

diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index 22815388d..6ae4b9726 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -75,7 +75,7 @@ export class FontIconBadge extends React.Component<FontIconBadgeProps> {
     onPointerDown = (e: React.PointerEvent) => {
         setupMoveUpEvents(this, e,
             (e: PointerEvent) => {
-                const dragData = new DragManager.DocumentDragData([this.props.collection]);
+                const dragData = new DragManager.DocumentDragData([this.props.collection!]);
                 DragManager.StartDocumentDrag([this._notifsRef.current!], dragData, e.x, e.y);
                 return true;
             },
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 0be0b5f30..9426f6afc 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -1,4 +1,4 @@
-import { action, computed, IReactionDisposer, observable, reaction, runInAction, ObservableMap } from 'mobx';
+import { action, computed, IReactionDisposer, observable, reaction, runInAction, ObservableMap, untracked } from 'mobx';
 import { observer } from "mobx-react";
 import { Dictionary } from 'typescript-collections';
 import { DataSym, Doc, DocListCast, WidthSym } from '../../../fields/Doc';
@@ -50,10 +50,10 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
     protected _multiTouchDisposer?: import("../../util/InteractionUtils").InteractionUtils.MultiTouchEventDisposer | undefined;
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ImageBox, fieldKey); }
     private _imgRef: React.RefObject<HTMLImageElement> = React.createRef();
-    private _curSuffix = "_m";
     private _dropDisposer?: DragManager.DragDropDisposer;
     private _disposers: { [name: string]: IReactionDisposer } = {};
-    @observable uploadIcon = uploadIcons.idle;
+    @observable _curSuffix = "";
+    @observable _uploadIcon = uploadIcons.idle;
 
     protected createDropTarget = (ele: HTMLDivElement) => {
         this._dropDisposer?.();
@@ -61,17 +61,25 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
     }
 
     componentDidMount() {
+        this._disposers.sizer = reaction(() => (
+            {
+                forceFull: this.props.renderDepth < 1 || this.layoutDoc._showFullRes,
+                scrSize: this.props.ScreenToLocalTransform().inverse().transformDirection(this.nativeSize.nativeWidth, this.nativeSize.nativeHeight)[0],
+                selected: this.props.isSelected()
+            }),
+            ({ forceFull, scrSize, selected }) => this._curSuffix = forceFull ? "_o" : scrSize < 100 ? "_s" : scrSize < 400 ? "_m" : scrSize < 800 || !selected ? "_l" : "_o",
+            { fireImmediately: true, delay: 1000 });
         this._disposers.selection = reaction(() => this.props.isSelected(),
             selected => !selected && setTimeout(() => {
                 Array.from(this._savedAnnotations.values()).forEach(v => v.forEach(a => a.remove()));
                 this._savedAnnotations.clear();
             }));
         this._disposers.path = reaction(() => ({ nativeSize: this.nativeSize, width: this.layoutDoc[WidthSym]() }),
-            action(({ nativeSize, width }) => {
+            ({ nativeSize, width }) => {
                 if (!this.layoutDoc._height) {
                     this.layoutDoc._height = width * nativeSize.nativeHeight / nativeSize.nativeWidth;
                 }
-            }),
+            },
             { fireImmediately: true });
     }
 
@@ -176,32 +184,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
         if (!/\.(png|jpg|jpeg|gif|webp)$/.test(lower)) return url.href;  //Why is this here
 
         const ext = path.extname(url.href);
-        const scrSize = this.props.ScreenToLocalTransform().inverse().transformDirection(this.nativeSize.nativeWidth, this.nativeSize.nativeHeight);
-        this._curSuffix = this.props.renderDepth < 1 || this.layoutDoc._showFullRes ? "_o" : scrSize[0] < 100 ? "_s" : scrSize[0] < 400 ? "_m" : scrSize[0] < 800 || !this.props.isSelected() ? "_l" : "_o";
         return url.href.replace(ext, this._curSuffix + ext);
     }
 
-    @observable _smallRetryCount = 1;
-    @observable _mediumRetryCount = 1;
-    @observable _largeRetryCount = 1;
-    @action retryPath = () => {
-        if (this._curSuffix === "_s") this._smallRetryCount++;
-        if (this._curSuffix === "_m") this._mediumRetryCount++;
-        if (this._curSuffix === "_l") this._largeRetryCount++;
-    }
-
-    @action onError = (error: any) => {
-        const timeout = this._curSuffix === "_s" ? this._smallRetryCount : this._curSuffix === "_m" ? this._mediumRetryCount : this._largeRetryCount;
-        if (timeout < 5) {
-            setTimeout(this.retryPath, 500);
-        } else {
-            const original = StrCast(this.dataDoc[this.fieldKey + "-originalUrl"]);
-            if (error.type === "error" && original) {
-                this.dataDoc[this.fieldKey] = new ImageField(original);
-            }
-        }
-    }
-
     considerGooglePhotosLink = () => {
         const remoteUrl = this.dataDoc.googlePhotosUrl;
         return !remoteUrl ? (null) : (<img draggable={false}
@@ -231,11 +216,11 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
             <img
                 id={"upload-icon"} draggable={false}
                 style={{ transformOrigin: "bottom right" }}
-                src={`/assets/${this.uploadIcon}`}
+                src={`/assets/${this._uploadIcon}`}
                 onClick={async () => {
                     const { dataDoc } = this;
                     const { success, failure, idle, loading } = uploadIcons;
-                    runInAction(() => this.uploadIcon = loading);
+                    runInAction(() => this._uploadIcon = loading);
                     const [{ accessPaths }] = await Networking.PostToServer("/uploadRemoteImage", { sources: [primary] });
                     dataDoc[this.props.fieldKey + "-originalUrl"] = primary;
                     let succeeded = true;
@@ -245,9 +230,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
                     } catch {
                         succeeded = false;
                     }
-                    runInAction(() => this.uploadIcon = succeeded ? success : failure);
+                    runInAction(() => this._uploadIcon = succeeded ? success : failure);
                     setTimeout(action(() => {
-                        this.uploadIcon = idle;
+                        this._uploadIcon = idle;
                         if (data) {
                             dataDoc[this.fieldKey] = data;
                         }
@@ -265,11 +250,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
         return { nativeWidth, nativeHeight, nativeOrientation };
     }
 
-    // this._curSuffix = "";
-    // if (w > 20) {
-    // if (w < 100 && this._smallRetryCount < 10) this._curSuffix = "_s";
-    // else if (w < 600 && this._mediumRetryCount < 10) this._curSuffix = "_m";
-    // else if (this._largeRetryCount < 10) this._curSuffix = "_l";
     @computed get paths() {
         const field = Cast(this.dataDoc[this.fieldKey], ImageField, null); // retrieve the primary image URL that is being rendered from the data doc
         const alts = DocListCast(this.dataDoc[this.fieldKey + "-alternates"]); // retrieve alternate documents that may be rendered as alternate images
@@ -300,20 +280,16 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
 
         return <div className="imageBox-cont" key={this.layoutDoc[Id]} ref={this.createDropTarget} onPointerDown={this.marqueeDown}>
             <div className="imageBox-fader" >
-                <img key={this._smallRetryCount + (this._mediumRetryCount << 4) + (this._largeRetryCount << 8)} // force cache to update on retrys
+                <img key="paths" ref={this._imgRef}
                     src={srcpath}
                     style={{ transform, transformOrigin }} draggable={false}
-                    width={nativeWidth}
-                    ref={this._imgRef}
-                    onError={this.onError} />
+                    width={nativeWidth} />
                 {fadepath === srcpath ? (null) : <div className="imageBox-fadeBlocker">
-                    <img className="imageBox-fadeaway"
-                        key={"fadeaway" + this._smallRetryCount + (this._mediumRetryCount << 4) + (this._largeRetryCount << 8)} // force cache to update on retrys
+                    <img className="imageBox-fadeaway" key={"fadeaway"} ref={this._imgRef}
                         src={fadepath}
                         style={{ transform, transformOrigin }} draggable={false}
-                        width={nativeWidth}
-                        ref={this._imgRef}
-                        onError={this.onError} /></div>}
+                        width={nativeWidth} />
+                </div>}
             </div>
             {this.considerDownloadIcon}
             {this.considerGooglePhotosLink()}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 5e94a7ae5..77dfd126e 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1421,11 +1421,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         </div>;
     }
     @computed get sidebarHandle() {
+        TraceMobx();
         const annotated = DocListCast(this.dataDoc[this.SidebarKey]).filter(d => d?.author).length;
         return (!annotated && !this.active()) ? (null) : <div className="formattedTextBox-sidebar-handle" onPointerDown={this.sidebarDown}
             style={{
                 left: `max(0px, calc(100% - ${this.sidebarWidthPercent} ${this.sidebarWidth() ? "- 5px" : "- 10px"}))`,
-                background: this.props.styleProvider?.(this.props.Document, this.props, StyleProp.WidgetColor + (annotated ? ":annotated" : ""))
+                background: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.WidgetColor + (annotated ? ":annotated" : ""))
             }} />;
     }
     @computed get sidebarCollection() {
-- 
cgit v1.2.3-70-g09d2

