From dc942e6228e003caa3754a72c0e126d64332a004 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 1 Nov 2022 18:29:11 -0400
Subject: fixes for goldenlayout to initialize more cleanly.  updated all old
 ReactDOM.render() to ReactDom.createRoot().  fixes for PDF/Web sidebar
 sizing.  added text from pdf selection anchors to sidebar notes.   fixed  PDF
 text selection to align properly.

---
 src/client/views/nodes/formattedText/DashDocView.tsx | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

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

diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 5f576be41..63ee7d1f3 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -1,7 +1,7 @@
 import { action, IReactionDisposer, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import { NodeSelection } from 'prosemirror-state';
-import * as ReactDOM from 'react-dom';
+import * as ReactDOM from 'react-dom/client';
 import { Doc, HeightSym, WidthSym } from '../../../../fields/Doc';
 import { Cast, NumCast, StrCast } from '../../../../fields/Types';
 import { emptyFunction, returnFalse, Utils } from '../../../../Utils';
@@ -15,6 +15,7 @@ import React = require('react');
 
 export class DashDocView {
     dom: HTMLSpanElement; // container for label and value
+    root: any;
 
     constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) {
         this.dom = document.createElement('span');
@@ -38,14 +39,13 @@ export class DashDocView {
             e.stopPropagation();
         };
 
-        ReactDOM.render(
-            <DashDocViewInternal docid={node.attrs.docid} alias={node.attrs.alias} width={node.attrs.width} height={node.attrs.height} hidden={node.attrs.hidden} fieldKey={node.attrs.fieldKey} tbox={tbox} view={view} node={node} getPos={getPos} />,
-            this.dom
+        this.root = ReactDOM.createRoot(this.dom);
+        this.root.render(
+            <DashDocViewInternal docid={node.attrs.docid} alias={node.attrs.alias} width={node.attrs.width} height={node.attrs.height} hidden={node.attrs.hidden} fieldKey={node.attrs.fieldKey} tbox={tbox} view={view} node={node} getPos={getPos} />
         );
-        (this as any).dom = this.dom;
     }
     destroy() {
-        ReactDOM.unmountComponentAtNode(this.dom);
+        // ReactDOM.unmountComponentAtNode(this.dom);
     }
     selectNode() {}
 }
-- 
cgit v1.2.3-70-g09d2


From 90bf9ea9e32ed695a36d0334e99fd859bbe51c15 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 10 Nov 2022 19:59:13 -0500
Subject: made alternate image use a field data-useAlt.  added alt images to
 preselements. fixed removing TabDoc documentviews from document view list. 
 added playing audio tags to preselements

---
 src/client/goldenLayout.js                         |  1 +
 src/client/util/LinkFollower.ts                    |  7 ++-----
 src/client/views/nodes/ImageBox.tsx                |  9 ++++++---
 .../nodes/formattedText/DashDocCommentView.tsx     |  3 +++
 .../views/nodes/formattedText/DashDocView.tsx      |  1 +
 .../views/nodes/formattedText/DashFieldView.tsx    |  2 +-
 .../views/nodes/formattedText/EquationView.tsx     |  1 +
 .../views/nodes/formattedText/SummaryView.tsx      |  1 +
 src/client/views/nodes/trails/PresBox.tsx          | 22 ++++++++++++++++++----
 9 files changed, 34 insertions(+), 13 deletions(-)

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

diff --git a/src/client/goldenLayout.js b/src/client/goldenLayout.js
index bc08b4d0b..9cb20d834 100644
--- a/src/client/goldenLayout.js
+++ b/src/client/goldenLayout.js
@@ -5408,6 +5408,7 @@
          * @returns {void}
          */
         _destroy: function () {
+            this._reactComponent.unmount();
           //  ReactDOM.unmountComponentAtNode(this._container.getElement()[0]);
             this._container.off('open', this._render, this);
             this._container.off('destroy', this._destroy, this);
diff --git a/src/client/util/LinkFollower.ts b/src/client/util/LinkFollower.ts
index 43b2caf88..1608a77f2 100644
--- a/src/client/util/LinkFollower.ts
+++ b/src/client/util/LinkFollower.ts
@@ -1,8 +1,5 @@
-import { action, observable, observe, runInAction } from 'mobx';
-import { computedFn } from 'mobx-utils';
-import { DirectLinksSym, Doc, DocListCast, DocListCastAsync, Field, Opt } from '../../fields/Doc';
-import { List } from '../../fields/List';
-import { ProxyField } from '../../fields/Proxy';
+import { action, runInAction } from 'mobx';
+import { Doc, DocListCast, Opt } from '../../fields/Doc';
 import { BoolCast, Cast, StrCast } from '../../fields/Types';
 import { DocumentDecorations } from '../views/DocumentDecorations';
 import { LightboxView } from '../views/LightboxView';
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index d02f181cc..d0df41023 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -8,7 +8,7 @@ import { List } from '../../../fields/List';
 import { ObjectField } from '../../../fields/ObjectField';
 import { createSchema } from '../../../fields/Schema';
 import { ComputedField } from '../../../fields/ScriptField';
-import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types';
 import { ImageField } from '../../../fields/URLField';
 import { TraceMobx } from '../../../fields/util';
 import { emptyFunction, OmitKeys, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../Utils';
@@ -120,6 +120,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
 
     @undoBatch
     resolution = () => (this.layoutDoc._showFullRes = !this.layoutDoc._showFullRes);
+    @undoBatch
+    setUseAlt = () => (this.layoutDoc[this.fieldKey + '-useAlt'] = !this.layoutDoc[this.fieldKey + '-useAlt']);
 
     @undoBatch
     rotate = action(() => {
@@ -182,6 +184,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
             const funcs: ContextMenuProps[] = [];
             funcs.push({ description: 'Rotate Clockwise 90', event: this.rotate, icon: 'expand-arrows-alt' });
             funcs.push({ description: `Show ${this.layoutDoc._showFullRes ? 'Dynamic Res' : 'Full Res'}`, event: this.resolution, icon: 'expand-arrows-alt' });
+            funcs.push({ description: `${this.layoutDoc[this.fieldKey + '-useAlt'] ? 'Show Primary' : 'Show Alternate'}`, event: this.setUseAlt, icon: 'expand-arrows-alt' });
             funcs.push({ description: 'Copy path', event: () => Utils.CopyText(this.choosePath(field.url)), icon: 'expand-arrows-alt' });
             if (!Doc.noviceMode) {
                 funcs.push({ description: 'Export to Google Photos', event: () => GooglePhotos.Transactions.UploadImages([this.props.Document]), icon: 'caret-square-right' });
@@ -335,8 +338,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
                 <div className="imageBox-fader" style={{ overflow: Array.from(this.props.docViewPath?.()).slice(-1)[0].fitWidth ? 'auto' : undefined }}>
                     <img key="paths" src={srcpath} style={{ transform, transformOrigin }} draggable={false} width={nativeWidth} />
                     {fadepath === srcpath ? null : (
-                        <div className={`imageBox-fadeBlocker${this.props.isHovering?.() ? '-hover' : ''}`}>
-                            <img className="imageBox-fadeaway" key={'fadeaway'} src={fadepath} style={{ transform, transformOrigin }} draggable={false} width={nativeWidth} />
+                        <div className={`imageBox-fadeBlocker${(this.props.isHovering?.() && this.layoutDoc[this.fieldKey + '-useAlt'] === undefined) || BoolCast(this.layoutDoc[this.fieldKey + '-useAlt']) ? '-hover' : ''}`}>
+                            <img className="imageBox-fadeaway" key="fadeaway" src={fadepath} style={{ transform, transformOrigin }} draggable={false} width={nativeWidth} />
                         </div>
                     )}
                 </div>
diff --git a/src/client/views/nodes/formattedText/DashDocCommentView.tsx b/src/client/views/nodes/formattedText/DashDocCommentView.tsx
index 4bff57842..fcd6e0c55 100644
--- a/src/client/views/nodes/formattedText/DashDocCommentView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocCommentView.tsx
@@ -36,6 +36,9 @@ export class DashDocCommentView {
         (this as any).dom = this.dom;
     }
 
+    destroy() {
+        this.root.unmount();
+    }
     deselectNode() {
         this.dom.classList.remove('ProseMirror-selectednode');
     }
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 63ee7d1f3..722d0cc4f 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -45,6 +45,7 @@ export class DashDocView {
         );
     }
     destroy() {
+        this.root.unmount();
         // ReactDOM.unmountComponentAtNode(this.dom);
     }
     selectNode() {}
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 41b92a3c7..1e7cb6ea5 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -47,7 +47,7 @@ export class DashFieldView {
         );
     }
     destroy() {
-        //this.root.unmount();
+        this.root.unmount();
     }
     deselectNode() {
         this.dom.classList.remove('ProseMirror-selectednode');
diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx
index 89f2a7c81..714ae458c 100644
--- a/src/client/views/nodes/formattedText/EquationView.tsx
+++ b/src/client/views/nodes/formattedText/EquationView.tsx
@@ -32,6 +32,7 @@ export class EquationView {
     _editor: EquationEditor | undefined;
     setEditor = (editor?: EquationEditor) => (this._editor = editor);
     destroy() {
+        this.root.unmount();
         // ReactDOM.unmountComponentAtNode(this.dom);
     }
     setSelection() {
diff --git a/src/client/views/nodes/formattedText/SummaryView.tsx b/src/client/views/nodes/formattedText/SummaryView.tsx
index 1fe6d822b..4e75d374c 100644
--- a/src/client/views/nodes/formattedText/SummaryView.tsx
+++ b/src/client/views/nodes/formattedText/SummaryView.tsx
@@ -42,6 +42,7 @@ export class SummaryView {
 
     className = (visible: boolean) => 'formattedTextBox-summarizer' + (visible ? '' : '-collapsed');
     destroy() {
+        this.root.unmount();
         // ReactDOM.unmountComponentAtNode(this.dom);
     }
     selectNode() {}
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 14f767595..c1973c4b4 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -349,7 +349,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         const pannable = [DocumentType.IMG].includes(target.type as any) || (target.type === DocumentType.COL && target._viewType === CollectionViewType.Freeform);
         const temporal = [DocumentType.AUDIO, DocumentType.VID].includes(target.type as any);
         const clippable = [DocumentType.COMPARISON].includes(target.type as any);
-        const dataview = [DocumentType.INK, DocumentType.COL].includes(target.type as any) && target.activeFrame === undefined;
+        const dataview = [DocumentType.INK, DocumentType.COL, DocumentType.IMG].includes(target.type as any) && target.activeFrame === undefined;
         const poslayoutview = [DocumentType.COL].includes(target.type as any) && target.activeFrame === undefined;
         const textview = [DocumentType.RTF].includes(target.type as any) && target.activeFrame === undefined;
         return { scrollable, pannable, temporal, clippable, dataview, textview, poslayoutview };
@@ -371,7 +371,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 dv?.brushView?.({ panX: (contentBounds[0] + contentBounds[2]) / 2, panY: (contentBounds[1] + contentBounds[3]) / 2, width: contentBounds[2] - contentBounds[0], height: contentBounds[3] - contentBounds[1] });
             }
         }
-        if (dataview && activeItem.presData !== undefined) Doc.GetProto(bestTarget)[Doc.LayoutFieldKey(bestTarget)] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData;
+        if (dataview && activeItem.presData !== undefined) {
+            const fkey = Doc.LayoutFieldKey(bestTarget);
+            Doc.GetProto(bestTarget)[fkey] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData;
+            bestTarget[fkey + '-useAlt'] = activeItem.presUseAlt;
+        }
         if (textview && activeItem.presData !== undefined) Doc.GetProto(bestTarget)[Doc.LayoutFieldKey(bestTarget)] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData;
         if (poslayoutview) {
             StrListCast(activeItem.presPinLayoutData)
@@ -434,7 +438,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         }
         if (pinProps?.pinDocContent) {
             pinDoc.presPinData = scrollable || temporal || pannable || clippable || dataview || textview || poslayoutview || pinProps.activeFrame !== undefined;
-            if (dataview) pinDoc.presData = targetDoc[Doc.LayoutFieldKey(targetDoc)] instanceof ObjectField ? (targetDoc[Doc.LayoutFieldKey(targetDoc)] as ObjectField)[Copy]() : targetDoc.data;
+            if (dataview) {
+                const fkey = Doc.LayoutFieldKey(targetDoc);
+                pinDoc.presUseAlt = targetDoc[fkey + '-useAlt'];
+                pinDoc.presData = targetDoc[fkey] instanceof ObjectField ? (targetDoc[fkey] as ObjectField)[Copy]() : targetDoc.data;
+            }
             if (textview) pinDoc.presData = targetDoc[Doc.LayoutFieldKey(targetDoc)] instanceof ObjectField ? (targetDoc[Doc.LayoutFieldKey(targetDoc)] as ObjectField)[Copy]() : targetDoc.text;
             if (scrollable) pinDoc.presPinViewScroll = pinDoc._scrollTop;
             if (clippable) pinDoc.presPinClipWidth = pinDoc._clipWidth;
@@ -541,8 +549,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         if (activeItem.presPinData || activeItem.presPinView) {
             clearTimeout(PresBox._navTimer);
             // targetDoc may or may not be displayed.  this gets the first available document (or alias) view that matches targetDoc
-            const bestTarget = DocumentManager.Instance.getFirstDocumentView(targetDoc)?.props.Document;
+            const bestTargetView = DocumentManager.Instance.getFirstDocumentView(targetDoc);
+            const bestTarget = bestTargetView?.props.Document;
             if (bestTarget) PresBox._navTimer = PresBox.restoreTargetDocView(bestTarget, activeItem);
+            activeItem.presPinAudioPlay && bestTargetView?.docView?.playAnnotation();
         }
     }
 
@@ -1369,6 +1379,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     {isPresCollection ? null : (
                         <div className="ribbon-box">
                             Effects
+                            <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
+                                <div className="presBox-subheading">Play Audio Annotation</div>
+                                <input className="presBox-checkbox" style={{ margin: 10 }} type="checkbox" onChange={() => (activeItem.presPinAudioPlay = !BoolCast(activeItem.presPinAudioPlay))} checked={BoolCast(activeItem.presPinAudioPlay)} />
+                            </div>
                             <div
                                 className="presBox-dropdown"
                                 onClick={action(e => {
-- 
cgit v1.2.3-70-g09d2

