From 9c63f3833f15cc995c2255b83923384686127f3e Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 1 Mar 2023 11:57:05 -0500
Subject: changed inPlace link following to be lightbox.  allowed collections
 to be labeled as lightboxes.  lightbox collections display link targets in an
 overlay that hides the rest of their content

---
 src/client/views/nodes/MapBox/MapBox.tsx | 1 -
 1 file changed, 1 deletion(-)

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

diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 039f11cd1..c182dfd19 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -331,7 +331,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         docs.forEach(doc => {
             if (doc.lat !== undefined && doc.lng !== undefined) {
                 const existingMarker = this.allMapMarkers.find(marker => marker.lat === doc.lat && marker.lng === doc.lng);
-                doc.onClickBehavior = 'enterPortal';
                 if (existingMarker) {
                     Doc.AddDocToList(existingMarker, 'data', doc);
                 } else {
-- 
cgit v1.2.3-70-g09d2


From 0fb643d13dc7dbdcd4ae0f4785f8f2bd3fbbc764 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 10 Mar 2023 21:48:11 -0500
Subject: fixed image anchors to save zoom/pan info and to focus() on content
 when following anchors.  fixed progresivized items in trails to not allow
 dragging items out or dropping new items in.

---
 src/client/documents/Documents.ts         |  3 ++
 src/client/views/collections/TreeView.tsx | 81 +++++++++++++++++--------------
 src/client/views/nodes/ImageBox.tsx       | 17 ++++++-
 src/client/views/nodes/MapBox/MapBox.tsx  |  7 +--
 src/client/views/nodes/trails/PresBox.tsx |  2 +-
 5 files changed, 68 insertions(+), 42 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 6296b0df4..4dc1c3b71 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -261,6 +261,9 @@ export class DocumentOptions {
     activeFrame?: number; // the active frame of a document in a frame base collection
     appearFrame?: number; // the frame in which the document appears
     viewTransitionTime?: number; // transition duration for view parameters
+    presPanX?: number; // panX saved as a view spec
+    presPanY?: number; // panY saved as a view spec
+    presViewScale?: number; // viewScale saved as a view Spec
     presTransition?: number; //the time taken for the transition TO a document
     presDuration?: number; //the duration of the slide in presentation view
     presZoomText?: boolean; // whether text anchors should shown in a larger box when following links to make them stand out
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index c8dc68eae..054d61d0c 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -8,7 +8,7 @@ import { List } from '../../../fields/List';
 import { RichTextField } from '../../../fields/RichTextField';
 import { listSpec } from '../../../fields/Schema';
 import { ComputedField, ScriptField } from '../../../fields/ScriptField';
-import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
+import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
 import { TraceMobx } from '../../../fields/util';
 import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, simulateMouseClick, Utils } from '../../../Utils';
 import { Docs, DocUtils } from '../../documents/Documents';
@@ -169,23 +169,6 @@ export class TreeView extends React.Component<TreeViewProps> {
     @computed get selected() {
         return SelectionManager.IsSelected(this._docRef);
     }
-    //      SelectionManager.Views().lastElement()?.props.Document === this.props.document; }
-
-    @observable _presTimer!: NodeJS.Timeout;
-    @observable _presKeyEventsActive: boolean = false;
-
-    @observable _selectedArray: ObservableMap = new ObservableMap<Doc, any>();
-    // the selected item's index
-    @computed get itemIndex() {
-        return NumCast(this.doc._itemIndex);
-    }
-    // the item that's active
-    @computed get activeItem() {
-        return this.childDocs ? Cast(this.childDocs[NumCast(this.doc._itemIndex)], Doc, null) : undefined;
-    }
-    @computed get targetDoc() {
-        return Cast(this.activeItem?.presentationTargetDoc, Doc, null);
-    }
 
     childDocList(field: string) {
         const layout = Cast(Doc.LayoutField(this.doc), Doc, null);
@@ -195,11 +178,17 @@ export class TreeView extends React.Component<TreeViewProps> {
             DocListCastOrNull(this.doc[field])
         ); // otherwise use the document's data field
     }
+    moving: boolean = false;
     @undoBatch move = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => {
         if (this.doc !== target && addDoc !== returnFalse) {
+            const canAdd1 = (this.props.parentTreeView as any).dropping || !(ComputedField.WithoutComputed(() => FieldValue(this.props.parentTreeView?.doc.data)) instanceof ComputedField);
+
             // bcz: this should all be running in a Temp undo batch instead of hackily testing for returnFalse
-            if (this.props.removeDoc?.(doc) === true) {
-                return addDoc(doc);
+            if (canAdd1 && this.props.removeDoc?.(doc) === true) {
+                this.props.parentTreeView instanceof TreeView && (this.props.parentTreeView.moving = true);
+                const res = addDoc(doc);
+                this.props.parentTreeView instanceof TreeView && (this.props.parentTreeView.moving = false);
+                return res;
             }
         }
         return false;
@@ -207,6 +196,7 @@ export class TreeView extends React.Component<TreeViewProps> {
     @undoBatch @action remove = (doc: Doc | Doc[], key: string) => {
         this.props.treeView.props.select(false);
         const ind = this.dataDoc[key].indexOf(doc);
+
         const res = (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && Doc.RemoveDocFromList(this.dataDoc, key, doc), true);
         res && ind > 0 && DocumentManager.Instance.getDocumentView(this.dataDoc[key][ind - 1], this.props.treeView.props.CollectionView)?.select(false);
         return res;
@@ -378,20 +368,32 @@ export class TreeView extends React.Component<TreeViewProps> {
         const docDragData = de.complete.docDragData;
         if (docDragData && pt[0] < rect.left + rect.width) {
             if (docDragData.draggedDocuments[0] === this.doc) return true;
-            if (this.dropDocuments(docDragData.droppedDocuments, before, inside, docDragData.dropAction, docDragData.moveDocument, docDragData.treeViewDoc === this.props.treeView.props.Document)) {
+            if (this.dropDocuments(docDragData.droppedDocuments, before, inside, docDragData.dropAction, docDragData.removeDocument, docDragData.moveDocument, docDragData.treeViewDoc === this.props.treeView.props.Document)) {
                 e.stopPropagation();
             }
         }
     };
 
-    dropDocuments(droppedDocuments: Doc[], before: boolean, inside: number | boolean, dropAction: dropActionType, moveDocument: DragManager.MoveFunction | undefined, forceAdd: boolean) {
+    dropping: boolean = false;
+    dropDocuments(droppedDocuments: Doc[], before: boolean, inside: number | boolean, dropAction: dropActionType, removeDocument: DragManager.RemoveFunction | undefined, moveDocument: DragManager.MoveFunction | undefined, forceAdd: boolean) {
         const parentAddDoc = (doc: Doc | Doc[]) => this.props.addDocument(doc, undefined, before);
-        const canAdd = (!this.props.treeView.outlineMode && !StrCast((inside ? this.props.document : this.props.containerCollection)?.freezeChildren).includes('add')) || forceAdd;
-        const localAdd = (doc: Doc) => (Doc.AddDocToList(this.dataDoc, this.fieldKey, doc) && ((doc.context = this.doc.context) || true) ? true : false);
-        const addDoc = !inside ? parentAddDoc : (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && localAdd(doc), true as boolean);
+        const localAdd = (doc: Doc | Doc[]) => {
+            const innerAdd = (doc: Doc) => {
+                const dataIsComputed = ComputedField.WithoutComputed(() => FieldValue(this.dataDoc[this.fieldKey])) instanceof ComputedField;
+                const added = (!dataIsComputed || (this.dropping && this.moving)) && Doc.AddDocToList(this.dataDoc, this.fieldKey, doc);
+                dataIsComputed && (doc.context = this.doc.context);
+                return added;
+            };
+            return (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && innerAdd(doc), true as boolean);
+        };
+        const addDoc = inside ? localAdd : parentAddDoc;
         const move = (!dropAction || dropAction === 'proto' || dropAction === 'move' || dropAction === 'same') && moveDocument;
+        const canAdd = (!this.props.treeView.outlineMode && !StrCast((inside ? this.props.document : this.props.containerCollection)?.freezeChildren).includes('add')) || forceAdd;
         if (canAdd) {
-            return UndoManager.RunInTempBatch(() => droppedDocuments.reduce((added, d) => (move ? move(d, undefined, addDoc) || (dropAction === 'proto' ? addDoc(d) : false) : addDoc(d)) || added, false));
+            this.props.parentTreeView instanceof TreeView && (this.props.parentTreeView.dropping = true);
+            const res = UndoManager.RunInTempBatch(() => droppedDocuments.reduce((added, d) => (move ? move(d, undefined, addDoc) || (dropAction === 'proto' ? addDoc(d) : false) : addDoc(d)) || added, false));
+            this.props.parentTreeView instanceof TreeView && (this.props.parentTreeView.dropping = false);
+            return res;
         }
         return false;
     }
@@ -437,12 +439,16 @@ export class TreeView extends React.Component<TreeViewProps> {
             const expandedWidth = () => this.props.panelWidth() - leftOffset.width;
             if (contents instanceof Doc || (Cast(contents, listSpec(Doc)) && Cast(contents, listSpec(Doc))!.length && Cast(contents, listSpec(Doc))![0] instanceof Doc)) {
                 const remDoc = (doc: Doc | Doc[]) => this.remove(doc, key);
-                const localAdd = (doc: Doc, addBefore?: Doc, before?: boolean) => {
-                    const added = Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true);
-                    added && (doc.context = this.doc.context);
-                    return added;
+                const moveDoc = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this.move(doc, target, addDoc);
+                const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => {
+                    const innerAdd = (doc: Doc) => {
+                        const dataIsComputed = ComputedField.WithoutComputed(() => FieldValue(this.dataDoc[key])) instanceof ComputedField;
+                        const added = (!dataIsComputed || (this.dropping && this.moving)) && Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true);
+                        dataIsComputed && (doc.context = this.doc.context);
+                        return added;
+                    };
+                    return (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && innerAdd(doc), true as boolean);
                 };
-                const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && localAdd(doc, addBefore, before), true);
                 contentElement = TreeView.GetChildElements(
                     contents instanceof Doc ? [contents] : DocListCast(contents),
                     this.props.treeView,
@@ -453,7 +459,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                     this.props.prevSibling,
                     addDoc,
                     remDoc,
-                    this.move,
+                    moveDoc,
                     this.props.dropAction,
                     this.props.addDocTab,
                     this.titleStyleProvider,
@@ -533,6 +539,7 @@ export class TreeView extends React.Component<TreeViewProps> {
             );
             const key = (expandKey === 'annotations' ? `${this.fieldKey}-` : '') + expandKey;
             const remDoc = (doc: Doc | Doc[]) => this.remove(doc, key);
+            const moveDoc = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this.move(doc, target, addDoc);
             const localAdd = (doc: Doc, addBefore?: Doc, before?: boolean) => {
                 // if there's a sort ordering specified that can be modified on drop (eg, zorder can be modified, alphabetical can't),
                 // then the modification would be done here
@@ -543,8 +550,10 @@ export class TreeView extends React.Component<TreeViewProps> {
                     docs.push(doc);
                     docs.sort((a, b) => (NumCast(a.zIndex) > NumCast(b.zIndex) ? 1 : -1)).forEach((d, i) => (d.zIndex = i));
                 }
-                const added = Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true);
-                added && (doc.context = this.doc.context);
+                const dataIsComputed = ComputedField.WithoutComputed(() => FieldValue(this.dataDoc[key])) instanceof ComputedField;
+                const added = (!dataIsComputed || (this.dropping && this.moving)) && Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true);
+                !dataIsComputed && added && (doc.context = this.doc.context);
+
                 return added;
             };
             const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && localAdd(doc, addBefore, before), true);
@@ -593,7 +602,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                                   this.props.prevSibling,
                                   addDoc,
                                   remDoc,
-                                  this.move,
+                                  moveDoc,
                                   StrCast(this.doc.childDropAction, this.props.dropAction) as dropActionType,
                                   this.props.addDocTab,
                                   this.titleStyleProvider,
@@ -1064,7 +1073,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         const before = pt[1] < rect.top + rect.height / 2;
         const inside = this.props.treeView.fileSysMode && !this.doc.isFolder ? false : pt[0] > Math.min(rect.left + 75, rect.left + rect.width * 0.75) || (!before && this.treeViewOpen && this.childDocs?.length ? true : false);
 
-        const docs = this.props.treeView.onTreeDrop(de, (docs: Doc[]) => this.dropDocuments(docs, before, inside, 'copy', undefined, false));
+        const docs = this.props.treeView.onTreeDrop(de, (docs: Doc[]) => this.dropDocuments(docs, before, inside, 'copy', undefined, undefined, false));
     };
 
     render() {
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index c6d4cb694..e60a03190 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -27,7 +27,7 @@ import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComp
 import { MarqueeAnnotator } from '../MarqueeAnnotator';
 import { AnchorMenu } from '../pdf/AnchorMenu';
 import { StyleProp } from '../StyleProvider';
-import { OpenWhere } from './DocumentView';
+import { DocFocusOptions, OpenWhere } from './DocumentView';
 import { FaceRectangles } from './FaceRectangles';
 import { FieldView, FieldViewProps } from './FieldView';
 import './ImageBox.scss';
@@ -73,7 +73,15 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
     getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
         const anchor =
             this._getAnchor?.(this._savedAnnotations, false) ?? // use marquee anchor, otherwise, save zoom/pan as anchor
-            Docs.Create.ImageanchorDocument({ title: 'ImgAnchor:' + this.rootDoc.title, presTransition: 1000, unrendered: true, annotationOn: this.rootDoc });
+            Docs.Create.ImageanchorDocument({
+                title: 'ImgAnchor:' + this.rootDoc.title,
+                presPanX: NumCast(this.layoutDoc._panX),
+                presPanY: NumCast(this.layoutDoc._panY),
+                presViewScale: Cast(this.layoutDoc._viewScale, 'number', null),
+                presTransition: 1000,
+                unrendered: true,
+                annotationOn: this.rootDoc,
+            });
         if (anchor) {
             if (!addAsAnnotation) anchor.backgroundColor = 'transparent';
             /* addAsAnnotation &&*/ this.addDocument(anchor);
@@ -433,6 +441,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
         this._marqueeing = undefined;
         this.props.select(false);
     };
+    focus = (anchor: Doc, options: DocFocusOptions) => this._ffref.current?.focus(anchor, options);
+
+    _ffref = React.createRef<CollectionFreeFormView>();
     savedAnnotations = () => this._savedAnnotations;
     render() {
         TraceMobx();
@@ -460,6 +471,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
                     overflow: this.layoutDoc.fitWidth || this.props.fitWidth?.(this.rootDoc) ? 'auto' : undefined,
                 }}>
                 <CollectionFreeFormView
+                    ref={this._ffref}
                     {...OmitKeys(this.props, ['NativeWidth', 'NativeHeight', 'setContentView']).omit}
                     renderDepth={this.props.renderDepth + 1}
                     fieldKey={this.annotationKey}
@@ -471,6 +483,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
                     PanelHeight={this.props.PanelHeight}
                     ScreenToLocalTransform={this.screenToLocalTransform}
                     select={emptyFunction}
+                    focus={this.focus}
                     getScrollHeight={this.getScrollHeight}
                     NativeDimScaling={returnOne}
                     whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index c182dfd19..0064a2022 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -21,6 +21,7 @@ import { AnchorMenu } from '../../pdf/AnchorMenu';
 import { Annotation } from '../../pdf/Annotation';
 import { SidebarAnnos } from '../../SidebarAnnos';
 import { FieldView, FieldViewProps } from '../FieldView';
+import { PinProps } from '../trails';
 import './MapBox.scss';
 import { MapBoxInfoWindow } from './MapBoxInfoWindow';
 
@@ -133,8 +134,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
     private _sidebarRef = React.createRef<SidebarAnnos>();
     private _ref: React.RefObject<HTMLDivElement> = React.createRef();
 
-    constructor(props: any) {
-        super(props);
+    componentDidMount() {
+        this.props.setContentView?.(this);
     }
 
     @action
@@ -525,7 +526,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         );
     }
 
-    getAnchor = (addAsAnnotation: boolean) => AnchorMenu.Instance?.GetAnchor(this._savedAnnotations, addAsAnnotation) ?? this.rootDoc;
+    getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => AnchorMenu.Instance?.GetAnchor(this._savedAnnotations, addAsAnnotation) ?? this.rootDoc;
 
     /**
      * render contents in allMapMarkers (e.g. images with exifData) into google maps as map marker
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 2d9aaeca4..dda96d8e7 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -557,7 +557,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 });
             setTimeout(() => Array.from(transitioned).forEach(action(doc => (doc._dataTransition = undefined))), transTime + 10);
         }
-        if ((pinDataTypes?.pannable || (!pinDataTypes && (activeItem.presPinViewBounds !== undefined || activeItem.presPanX !== undefined || activeItem.presViewScale !== undefined))) && !PresBox.targetRenderedDoc(activeItem)._isGroup) {
+        if ((pinDataTypes?.pannable || (!pinDataTypes && (activeItem.presPinViewBounds !== undefined || activeItem.presPanX !== undefined || activeItem.presViewScale !== undefined))) && !bestTarget._isGroup) {
             const contentBounds = Cast(activeItem.presPinViewBounds, listSpec('number'));
             if (contentBounds) {
                 const viewport = { panX: (contentBounds[0] + contentBounds[2]) / 2, panY: (contentBounds[1] + contentBounds[3]) / 2, width: contentBounds[2] - contentBounds[0], height: contentBounds[3] - contentBounds[1] };
-- 
cgit v1.2.3-70-g09d2

