From 5e2f64f3ee172e37d0d3277637a7778b640a2066 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 30 Jan 2023 15:23:40 -0500
Subject: fixed pointerEvents for text box footnotes.  fixed keyvalue editing
 to not typecheck.  fixed schema header field editing from keyvalue pane. 
 fixed webBox error causing overlayview to not work for Repls and others.  
 fixed some layout issues with stackingview columns.

---
 src/client/views/nodes/formattedText/FormattedTextBox.tsx | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(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 8407eee96..80832c9be 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1611,7 +1611,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
     @action
     onBlur = (e: any) => {
         if (this.ProseRef?.children[0] !== e.nativeEvent.target) return;
-        this.autoLink();
+        if (!(this.EditorView?.state.selection instanceof NodeSelection) || this.EditorView.state.selection.node.type !== this.EditorView.state.schema.nodes.footnote) {
+            this.autoLink();
+        }
         FormattedTextBox.Focused === this && (FormattedTextBox.Focused = undefined);
         if (RichTextMenu.Instance?.view === this._editorView && !this.props.isSelected(true)) {
             RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined);
-- 
cgit v1.2.3-70-g09d2


From 294412015c0f3dbfaa8982f1dcab100fbfdd036f Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 1 Feb 2023 02:22:00 -0500
Subject: fixed ungrouping documents on video/image/etc.  fixed undoing
 deleting collections to reset annotationOn field.  fixed setting size in text
 box with richtext menu buttons and not losing focus and having stored marks
 get lost.

---
 src/client/views/DocComponent.tsx                  | 11 +--
 .../views/collections/CollectionCarouselView.tsx   | 94 ++++++++++++----------
 .../views/collections/CollectionStackingView.tsx   |  5 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 16 ++--
 .../collections/collectionFreeForm/MarqueeView.tsx | 20 ++---
 .../views/nodes/formattedText/FormattedTextBox.tsx |  8 ++
 6 files changed, 81 insertions(+), 73 deletions(-)

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

diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 78ab2b3d4..7c81d92d4 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -151,13 +151,10 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps>()
             const indocs = doc instanceof Doc ? [doc] : doc;
             const docs = indocs.filter(doc => [AclEdit, AclAdmin].includes(effectiveAcl) || GetEffectiveAcl(doc) === AclAdmin);
             if (docs.length) {
-                setTimeout(() =>
-                    docs.map(doc => {
-                        // this allows 'addDocument' to see the annotationOn field in order to create a pushin
-                        Doc.SetInPlace(doc, 'followLinkToggle', undefined, true);
-                        doc.annotationOn === this.props.Document && Doc.SetInPlace(doc, 'annotationOn', undefined, true);
-                    })
-                );
+                docs.map(doc => {
+                    Doc.SetInPlace(doc, 'followLinkToggle', undefined, true);
+                    doc.annotationOn === this.props.Document && Doc.SetInPlace(doc, 'annotationOn', undefined, true);
+                });
                 const targetDataDoc = this.dataDoc;
                 const value = DocListCast(targetDataDoc[annotationKey ?? this.annotationKey]);
                 const toRemove = value.filter(v => docs.includes(v));
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index abb4b6bc6..32f6207ed 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -9,54 +9,58 @@ import { DragManager } from '../../util/DragManager';
 import { DocumentView, DocumentViewProps } from '../nodes/DocumentView';
 import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
 import { StyleProp } from '../StyleProvider';
-import "./CollectionCarouselView.scss";
+import './CollectionCarouselView.scss';
 import { CollectionSubView } from './CollectionSubView';
 
 @observer
 export class CollectionCarouselView extends CollectionSubView() {
     private _dropDisposer?: DragManager.DragDropDisposer;
 
-    componentWillUnmount() { this._dropDisposer?.(); }
+    componentWillUnmount() {
+        this._dropDisposer?.();
+    }
 
-    protected createDashEventsTarget = (ele: HTMLDivElement | null) => { //used for stacking and masonry view
+    protected createDashEventsTarget = (ele: HTMLDivElement | null) => {
+        //used for stacking and masonry view
         this._dropDisposer?.();
         if (ele) {
             this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc);
         }
-    }
+    };
 
     advance = (e: React.MouseEvent) => {
         e.stopPropagation();
         this.layoutDoc._itemIndex = (NumCast(this.layoutDoc._itemIndex) + 1) % this.childLayoutPairs.length;
-    }
+    };
     goback = (e: React.MouseEvent) => {
         e.stopPropagation();
         this.layoutDoc._itemIndex = (NumCast(this.layoutDoc._itemIndex) - 1 + this.childLayoutPairs.length) % this.childLayoutPairs.length;
-    }
-    captionStyleProvider = (doc: (Doc | undefined), captionProps: Opt<DocumentViewProps>, property: string): any => {
+    };
+    captionStyleProvider = (doc: Doc | undefined, captionProps: Opt<DocumentViewProps>, property: string): any => {
         // first look for properties on the document in the carousel, then fallback to properties on the container
-        const childValue = doc?.["caption-" + property] ? this.props.styleProvider?.(doc, captionProps, property) : undefined;
+        const childValue = doc?.['caption-' + property] ? this.props.styleProvider?.(doc, captionProps, property) : undefined;
         return childValue ?? this.props.styleProvider?.(this.layoutDoc, captionProps, property);
-    }
+    };
     panelHeight = () => this.props.PanelHeight() - (StrCast(this.layoutDoc._showCaption) ? 50 : 0);
     onContentDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick);
     onContentClick = () => ScriptCast(this.layoutDoc.onChildClick);
     @computed get content() {
         const index = NumCast(this.layoutDoc._itemIndex);
         const curDoc = this.childLayoutPairs?.[index];
-        const captionProps = { ...OmitKeys(this.props, ["setHeight",]).omit, fieldKey: "caption" };
-        const marginX = NumCast(this.layoutDoc["caption-xMargin"]);
-        const marginY = NumCast(this.layoutDoc["caption-yMargin"]);
+        const captionProps = { ...OmitKeys(this.props, ['setHeight']).omit, fieldKey: 'caption' };
+        const marginX = NumCast(this.layoutDoc['caption-xMargin']);
+        const marginY = NumCast(this.layoutDoc['caption-yMargin']);
         const showCaptions = StrCast(this.layoutDoc._showCaption);
-        return !(curDoc?.layout instanceof Doc) ? (null) :
+        return !(curDoc?.layout instanceof Doc) ? null : (
             <>
                 <div className="collectionCarouselView-image" key="image">
-                    <DocumentView  {...OmitKeys(this.props, ["setHeight", "NativeWidth", "NativeHeight", "childLayoutTemplate", "childLayoutString"]).omit}
+                    <DocumentView
+                        {...OmitKeys(this.props, ['setHeight', 'NativeWidth', 'NativeHeight', 'childLayoutTemplate', 'childLayoutString']).omit}
                         onDoubleClick={this.onContentDoubleClick}
                         onClick={this.onContentClick}
                         hideCaptions={showCaptions ? true : false}
                         renderDepth={this.props.renderDepth + 1}
-                        ContainingCollectionView={this}
+                        ContainingCollectionView={this.props.CollectionView}
                         LayoutTemplate={this.props.childLayoutTemplate}
                         LayoutTemplateString={this.props.childLayoutString}
                         Document={curDoc.layout}
@@ -65,40 +69,46 @@ export class CollectionCarouselView extends CollectionSubView() {
                         bringToFront={returnFalse}
                     />
                 </div>
-                <div className="collectionCarouselView-caption" key="caption"
+                <div
+                    className="collectionCarouselView-caption"
+                    key="caption"
                     style={{
-                        display: showCaptions ? undefined : "none",
+                        display: showCaptions ? undefined : 'none',
                         borderRadius: this.props.styleProvider?.(this.layoutDoc, captionProps, StyleProp.BorderRounding),
-                        marginRight: marginX, marginLeft: marginX,
-                        width: `calc(100% - ${marginX * 2}px)`
+                        marginRight: marginX,
+                        marginLeft: marginX,
+                        width: `calc(100% - ${marginX * 2}px)`,
                     }}>
-                    <FormattedTextBox key={index} {...captionProps}
-                        fieldKey={showCaptions}
-                        styleProvider={this.captionStyleProvider}
-                        Document={curDoc.layout}
-                        DataDoc={undefined} />
+                    <FormattedTextBox key={index} {...captionProps} fieldKey={showCaptions} styleProvider={this.captionStyleProvider} Document={curDoc.layout} DataDoc={undefined} />
                 </div>
-            </>;
+            </>
+        );
     }
     @computed get buttons() {
-        return <>
-            <div key="back" className="carouselView-back" onClick={this.goback}>
-                <FontAwesomeIcon icon={"chevron-left"} size={"2x"} />
-            </div>
-            <div key="fwd" className="carouselView-fwd" onClick={this.advance}>
-                <FontAwesomeIcon icon={"chevron-right"} size={"2x"} />
-            </div>
-        </>;
+        return (
+            <>
+                <div key="back" className="carouselView-back" onClick={this.goback}>
+                    <FontAwesomeIcon icon={'chevron-left'} size={'2x'} />
+                </div>
+                <div key="fwd" className="carouselView-fwd" onClick={this.advance}>
+                    <FontAwesomeIcon icon={'chevron-right'} size={'2x'} />
+                </div>
+            </>
+        );
     }
 
     render() {
-        return <div className="collectionCarouselView-outer" ref={this.createDashEventsTarget}
-            style={{
-                background: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor),
-                color: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color),
-            }}>
-            {this.content}
-            {this.props.Document._chromeHidden ? (null) : this.buttons}
-        </div>;
+        return (
+            <div
+                className="collectionCarouselView-outer"
+                ref={this.createDashEventsTarget}
+                style={{
+                    background: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor),
+                    color: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color),
+                }}>
+                {this.content}
+                {this.props.Document._chromeHidden ? null : this.buttons}
+            </div>
+        );
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index acf59b5da..2f495d55c 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -639,6 +639,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
         return sections.map((section, i) => (this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1], i === 0)));
     }
 
+    return35 = () => 35;
     @computed get buttonMenu() {
         const menuDoc: Doc = Cast(this.rootDoc.buttonMenuDoc, Doc, null);
         // TODO:glr Allow support for multiple buttons
@@ -660,8 +661,8 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                         rootSelected={this.props.isSelected}
                         removeDocument={this.props.removeDocument}
                         ScreenToLocalTransform={Transform.Identity}
-                        PanelWidth={() => 35}
-                        PanelHeight={() => 35}
+                        PanelWidth={this.return35}
+                        PanelHeight={this.return35}
                         renderDepth={this.props.renderDepth}
                         focus={emptyFunction}
                         styleProvider={this.props.styleProvider}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 5cf4cb31f..695d500e9 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -12,7 +12,7 @@ import { ObjectField } from '../../../../fields/ObjectField';
 import { RichTextField } from '../../../../fields/RichTextField';
 import { listSpec } from '../../../../fields/Schema';
 import { ScriptField } from '../../../../fields/ScriptField';
-import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
+import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
 import { ImageField } from '../../../../fields/URLField';
 import { TraceMobx } from '../../../../fields/util';
 import { GestureUtils } from '../../../../pen-gestures/GestureUtils';
@@ -269,7 +269,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         const dispTime = NumCast(doc._timecodeToShow, -1);
         const endTime = NumCast(doc._timecodeToHide, dispTime + 1.5);
         const curTime = NumCast(this.Document._currentTimecode, -1);
-        return dispTime === -1 || (curTime - dispTime >= -1e-4 && curTime <= endTime);
+        return dispTime === -1 || curTime === -1 || (curTime - dispTime >= -1e-4 && curTime <= endTime);
     }
 
     @action
@@ -1344,15 +1344,18 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             case OpenWhere.inParent:
                 return this.props.addDocument?.(doc) || false;
             case OpenWhere.inParentFromScreen:
+                const docContext = DocCast((doc instanceof Doc ? doc : doc?.[0])?.context);
                 return (
-                    this.props.addDocument?.(
+                    (this.props.addDocument?.(
                         (doc instanceof Doc ? [doc] : doc).map(doc => {
                             const pt = this.getTransform().transformPoint(NumCast(doc.x), NumCast(doc.y));
                             doc.x = pt[0];
                             doc.y = pt[1];
                             return doc;
                         })
-                    ) || false
+                    ) &&
+                        (!docContext || this.props.removeDocument?.(docContext))) ||
+                    false
                 );
             case OpenWhere.inPlace:
                 if (this.layoutDoc.isInPlaceContainer) {
@@ -1747,7 +1750,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             doc.y = scr?.[1];
         });
         this.props.addDocTab(childDocs as any as Doc, OpenWhere.inParentFromScreen);
-        this.props.ContainingCollectionView?.removeDocument(this.props.Document);
     };
 
     @undoBatch
@@ -1766,7 +1768,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     toggleNativeDimensions = () => Doc.toggleNativeDimensions(this.layoutDoc, 1, this.nativeWidth, this.nativeHeight);
 
     onContextMenu = (e: React.MouseEvent) => {
-        if (this.props.isAnnotationOverlay || this.props.Document.annotationOn || !ContextMenu.Instance) return;
+        if (this.props.isAnnotationOverlay || !ContextMenu.Instance) return;
 
         const appearance = ContextMenu.Instance.findByDescription('Appearance...');
         const appearanceItems = appearance && 'subitems' in appearance ? appearance.subitems : [];
@@ -1786,7 +1788,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         });
         appearanceItems.push({ description: `Pin View`, event: () => TabDocView.PinDoc(this.rootDoc, { pinViewport: MarqueeView.CurViewBounds(this.rootDoc, this.props.PanelWidth(), this.props.PanelHeight()) }), icon: 'map-pin' });
         //appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: "compress-arrows-alt" });
-        this.props.ContainingCollectionView && appearanceItems.push({ description: 'Ungroup collection', event: this.promoteCollection, icon: 'table' });
+        appearanceItems.push({ description: 'Ungroup collection', event: this.promoteCollection, icon: 'table' });
 
         this.props.Document._isGroup && this.Document.transcription && appearanceItems.push({ description: 'Ink to text', event: () => this.transcribeStrokes(false), icon: 'font' });
 
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index dcbadc5f3..0b7854926 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -433,25 +433,15 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
     @action
     collection = (e: KeyboardEvent | React.PointerEvent | undefined, group?: boolean) => {
         const selected = this.marqueeSelect(false);
+        const activeFrame = selected.reduce((v, d) => v ?? Cast(d._activeFrame, 'number', null), undefined as number | undefined);
         if (e instanceof KeyboardEvent ? 'cg'.includes(e.key) : true) {
-            selected.map(
-                action(d => {
-                    const dx = NumCast(d.x);
-                    const dy = NumCast(d.y);
-                    delete d.x;
-                    delete d.y;
-                    delete d.activeFrame;
-                    delete d._timecodeToShow; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
-                    delete d._timecodeToHide; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
-                    d.x = dx - this.Bounds.left - this.Bounds.width / 2;
-                    d.y = dy - this.Bounds.top - this.Bounds.height / 2;
-                    return d;
-                })
-            );
             this.props.removeDocument?.(selected);
         }
-        // TODO: nda - this is the code to actually get a new grouped collection
+
         const newCollection = this.getCollection(selected, (e as KeyboardEvent)?.key === 't' ? Docs.Create.StackingDocument : undefined, group);
+        newCollection._panX = this.Bounds.left + this.Bounds.width / 2;
+        newCollection._panY = this.Bounds.top + this.Bounds.height / 2;
+        newCollection._currentFrame = activeFrame;
         this.props.addDocument?.(newCollection);
         this.props.selectDocuments([newCollection]);
         MarqueeOptionsMenu.Instance.fadeOut(true);
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 80832c9be..619c59f0e 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1612,7 +1612,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
     onBlur = (e: any) => {
         if (this.ProseRef?.children[0] !== e.nativeEvent.target) return;
         if (!(this.EditorView?.state.selection instanceof NodeSelection) || this.EditorView.state.selection.node.type !== this.EditorView.state.schema.nodes.footnote) {
+            const stordMarks = this._editorView?.state.storedMarks?.slice();
             this.autoLink();
+            if (this._editorView?.state.tr) {
+                const tr = stordMarks?.reduce((tr, m) => {
+                    tr.addStoredMark(m);
+                    return tr;
+                }, this._editorView.state.tr);
+                tr && this._editorView.dispatch(tr);
+            }
         }
         FormattedTextBox.Focused === this && (FormattedTextBox.Focused = undefined);
         if (RichTextMenu.Instance?.view === this._editorView && !this.props.isSelected(true)) {
-- 
cgit v1.2.3-70-g09d2

