From d95730d904612640184ca6fdc00864b0c81b0c0c Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 18 Sep 2024 20:46:38 -0400
Subject: lots of changes to fix dragging cards, integrate iconTags with other
 tags, sizing docs when selected to fit window,

---
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx  | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

(limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index dbf781e63..cbbf063b4 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable react/jsx-props-no-spreading */
 import { Bezier } from 'bezier-js';
 import { Colors } from 'browndash-components';
 import { Property } from 'csstype';
@@ -1211,7 +1210,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 for (let j = 0; j < otherCtrlPts.length - 3; j += 4) {
                     const neighboringSegment = i === j || i === j - 4 || i === j + 4;
                     // Ensuring that the curve intersected by the eraser is not checked for further ink intersections.
-                    // eslint-disable-next-line no-continue
                     if (ink?.Document === otherInk.Document && neighboringSegment) continue;
 
                     const otherCurve = new Bezier(otherCtrlPts.slice(j, j + 4).map(p => ({ x: p.X, y: p.Y })));
@@ -1481,8 +1479,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         const childData = entry.pair.data;
         return (
             <CollectionFreeFormDocumentView
-                // eslint-disable-next-line react/jsx-props-no-spreading, @typescript-eslint/no-explicit-any
-                {...(OmitKeys(entry, ['replica', 'pair']).omit as any)}
+                {...(OmitKeys(entry, ['replica', 'pair']).omit as { x: number; y: number; z: number; width: number; height: number })}
                 key={childLayout[Id] + (entry.replica || '')}
                 Document={childLayout}
                 reactParent={this}
-- 
cgit v1.2.3-70-g09d2


From 65a1a272b15fb9c08ef75a12946d7f3751a500c7 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 19 Sep 2024 02:54:28 -0400
Subject: added stop propagation for clicking on tags and icon tags.  fixed
 dragging crash from doc nested in card view to card view.  still needs more
 work for card view to honor canEmbed

---
 src/client/views/TagsView.tsx                      | 25 +++++++++++++++--
 .../views/collections/CollectionCardDeckView.tsx   | 32 +++++++++++-----------
 .../views/collections/CollectionNoteTakingView.tsx |  1 -
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  1 -
 src/client/views/nodes/IconTagBox.tsx              | 14 ++++++----
 5 files changed, 47 insertions(+), 26 deletions(-)

(limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx')

diff --git a/src/client/views/TagsView.tsx b/src/client/views/TagsView.tsx
index a9224e437..cae30218c 100644
--- a/src/client/views/TagsView.tsx
+++ b/src/client/views/TagsView.tsx
@@ -207,7 +207,10 @@ export class TagItem extends ObservableReactComponent<TagItemProps> {
                 return false;
             },
             returnFalse,
-            emptyFunction
+            clickEv => {
+                clickEv.stopPropagation();
+                this._props.setToEditing();
+            }
         );
         e.preventDefault();
     };
@@ -220,7 +223,7 @@ export class TagItem extends ObservableReactComponent<TagItemProps> {
         this._props.tagDoc && setTimeout(() => this._props.docs.forEach(doc => TagItem.addTagToDoc(doc, this._props.tag))); // bcz: hack to make sure that Docs are added to their tag Doc collection since metadata can get set anywhere without a guard triggering an add to the collection
         const metadata = this._props.tag.startsWith('@') ? this._props.tag.replace(/^@/, '') : '';
         return (
-            <div className={'tagItem' + (!this._props.tagDoc ? ' faceItem' : '')} onClick={this._props.setToEditing} onPointerDown={this.handleDragStart} ref={this._ref}>
+            <div className={'tagItem' + (!this._props.tagDoc ? ' faceItem' : '')} onPointerDown={this.handleDragStart} ref={this._ref}>
                 {metadata ? (
                     <span>
                         <b style={{ fontSize: 'smaller' }}>{'@' + metadata}&nbsp;</b>
@@ -364,7 +367,23 @@ export class TagsView extends ObservableReactComponent<TagViewProps> {
                 <div className="tagsView-content" style={{ width: '100%' }}>
                     <div className="tagsView-list">
                         {this._props.Views.length === 1 && !this.View.showTags ? null : ( //
-                            <IconButton style={{ width: '8px' }} tooltip="Close Menu" onPointerDown={() => this.setToEditing(!this._isEditing)} icon={<FontAwesomeIcon icon={this._isEditing ? 'chevron-up' : 'chevron-down'} size="sm" />} />
+                            <IconButton
+                                style={{ width: '8px' }}
+                                tooltip="Close Menu"
+                                onPointerDown={e =>
+                                    setupMoveUpEvents(
+                                        this,
+                                        e,
+                                        returnFalse,
+                                        emptyFunction,
+                                        upEv => {
+                                            this.setToEditing(!this._isEditing);
+                                            upEv.stopPropagation();
+                                        }
+                                    )
+                                }
+                                icon={<FontAwesomeIcon icon={this._isEditing ? 'chevron-up' : 'chevron-down'} size="sm" />}
+                            />
                         )}
                         <IconTagBox Views={this._props.Views} IsEditing={this._isEditing} />
                         {Array.from(tagsList)
diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx
index 8fea3dbd6..cab7d51e4 100644
--- a/src/client/views/collections/CollectionCardDeckView.tsx
+++ b/src/client/views/collections/CollectionCardDeckView.tsx
@@ -6,6 +6,7 @@ import { emptyFunction } from '../../../Utils';
 import { Doc, StrListCast } from '../../../fields/Doc';
 import { DocData } from '../../../fields/DocSymbols';
 import { Id } from '../../../fields/FieldSymbols';
+import { List } from '../../../fields/List';
 import { BoolCast, DateCast, DocCast, NumCast, RTFCast, ScriptCast, StrCast } from '../../../fields/Types';
 import { URLField } from '../../../fields/URLField';
 import { gptImageLabel } from '../../apis/gpt/GPT';
@@ -21,7 +22,6 @@ import { DocumentView } from '../nodes/DocumentView';
 import { GPTPopup, GPTPopupMode } from '../pdf/GPTPopup/GPTPopup';
 import './CollectionCardDeckView.scss';
 import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
-import { List } from '../../../fields/List';
 
 enum cardSortings {
     Time = 'time',
@@ -51,7 +51,6 @@ export class CollectionCardView extends CollectionSubView() {
     @observable _docRefs = new ObservableMap<Doc, DocumentView>();
     @observable _maxRowCount = 10;
     @observable _docDraggedIndex: number = -1;
-    @observable _isACardBeingDragged: boolean = false;
     @observable overIndex: number = -1;
 
     static imageUrlToBase64 = async (imageUrl: string): Promise<string> => {
@@ -76,7 +75,6 @@ export class CollectionCardView extends CollectionSubView() {
         makeObservable(this);
         this.setRegenerateCallback();
     }
-
     protected createDashEventsTarget = (ele: HTMLDivElement | null) => {
         this._dropDisposer?.();
         if (ele) {
@@ -269,11 +267,10 @@ export class CollectionCardView extends CollectionSubView() {
      */
 
     @action
-    onPointerMove = (e: React.PointerEvent<HTMLDivElement>) => {
-        if (DragManager.docsBeingDragged.length != 0) {
-            this._isACardBeingDragged = true;
-
-            const newIndex = this.findCardDropIndex(e.clientX, e.clientY);
+    onPointerMove = (x: number, y: number) => {
+        this._docDraggedIndex = -1;
+        if (DragManager.docsBeingDragged.length) {
+            const newIndex = this.findCardDropIndex(x, y);
 
             if (newIndex !== this._docDraggedIndex && newIndex != -1) {
                 this._docDraggedIndex = newIndex;
@@ -297,18 +294,19 @@ export class CollectionCardView extends CollectionSubView() {
     onInternalDrop = undoable(
         action((e: Event, de: DragManager.DropEvent) => {
             if (de.complete.docDragData) {
-                this._isACardBeingDragged = false;
                 const dragIndex = this._docDraggedIndex;
-                if (dragIndex > -1) {
+                const draggedDoc = DragManager.docsBeingDragged[0];
+                if (dragIndex > -1 && draggedDoc) {
                     this._docDraggedIndex = -1;
-                    const draggedDoc = DragManager.docsBeingDragged[0];
                     const sorted = this.sortedDocs;
                     const originalIndex = sorted.findIndex(doc => doc === draggedDoc);
 
                     this.Document.cardSort = '';
-                    sorted.splice(originalIndex, 1);
+                    originalIndex !== -1 && sorted.splice(originalIndex, 1);
                     sorted.splice(dragIndex, 0, draggedDoc);
-                    this.dataDoc[this.fieldKey] = new List<Doc>(sorted);
+                    if (de.complete.docDragData.removeDocument?.(draggedDoc)) {
+                        this.dataDoc[this.fieldKey] = new List<Doc>(sorted);
+                    }
                 }
                 e.stopPropagation();
                 return true;
@@ -397,7 +395,7 @@ export class CollectionCardView extends CollectionSubView() {
             const draggedDoc = DragManager.docsBeingDragged[0];
             const originalIndex = docs.findIndex(doc => doc === draggedDoc);
 
-            docs.splice(originalIndex, 1);
+            originalIndex !== -1 && docs.splice(originalIndex, 1);
             docs.splice(dragIndex, 0, draggedDoc);
         }
 
@@ -619,7 +617,8 @@ export class CollectionCardView extends CollectionSubView() {
             const realIndex = sortedDocs.indexOf(doc);
             const calcRowIndex = this.overflowIndexCalc(realIndex);
             const amCards = this.overflowAmCardsCalc(realIndex);
-            const isSelected = DocumentView.SelectedDocs().includes(doc);
+            const view = DocumentView.getDocumentView(doc, this.DocumentView?.());
+            const isSelected = view?.ComponentView?.isAnyChildContentActive?.() || view?.IsSelected ? true : false;
 
             const childScreenToLocal = () => {
                 this._forceChildXf;
@@ -645,6 +644,7 @@ export class CollectionCardView extends CollectionSubView() {
                     key={doc[Id]}
                     className={`card-item${isSelected ? '-active' : anySelected ? '-inactive' : ''}`}
                     onPointerUp={() => {
+                        if (DocumentView.SelectedDocs().includes(doc)) return;
                         // this turns off documentDecorations during a transition, then turns them back on afterward.
                         SnappingManager.SetIsResizing(doc[Id]);
                         setTimeout(
@@ -675,9 +675,9 @@ export class CollectionCardView extends CollectionSubView() {
 
         return (
             <div
-                onPointerMove={e => this.onPointerMove(e)}
                 className="collectionCardView-outer"
                 ref={(ele: HTMLDivElement | null) => this.createDashEventsTarget(ele)}
+                onPointerMove={e => this.onPointerMove(e.clientX, e.clientY)}
                 onDrop={this.onExternalDrop.bind(this)}
                 style={{
                     background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string,
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index e1f0a3e41..ac8e37358 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -653,7 +653,6 @@ export class CollectionNoteTakingView extends CollectionSubView() {
         const sections = Array.from(this.Sections.entries());
         return sections.reduce((list, sec, i) => {
             list.push(this.sectionNoteTaking(sec[0], sec[1]));
-            // eslint-disable-next-line react/no-array-index-key
             i !== sections.length - 1 && list.push(<CollectionNoteTakingViewDivider key={`divider${i}`} isContentActive={this.isContentActive} index={i} setColumnStartXCoords={this.setColumnStartXCoords} xMargin={this.xMargin} />);
             return list;
         }, [] as JSX.Element[]);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index cbbf063b4..f106eba26 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1783,7 +1783,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 if (!code.includes('dashDiv')) {
                     const script = CompileScript(code, { params: { docView: 'any' }, typecheck: false, editable: true });
                     if (script.compiled) script.run({ this: this.DocumentView?.() });
-                    // eslint-disable-next-line no-eval
                 } else code && !first && eval?.(code);
             },
             { fireImmediately: true }
diff --git a/src/client/views/nodes/IconTagBox.tsx b/src/client/views/nodes/IconTagBox.tsx
index ea1c3591a..70992e28a 100644
--- a/src/client/views/nodes/IconTagBox.tsx
+++ b/src/client/views/nodes/IconTagBox.tsx
@@ -4,7 +4,7 @@ import { Tooltip } from '@mui/material';
 import { computed } from 'mobx';
 import { observer } from 'mobx-react';
 import React from 'react';
-import { numberRange } from '../../../Utils';
+import { emptyFunction, numberRange } from '../../../Utils';
 import { Doc, StrListCast } from '../../../fields/Doc';
 import { StrCast } from '../../../fields/Types';
 import { SnappingManager } from '../../util/SnappingManager';
@@ -15,6 +15,7 @@ import { PropertiesView } from '../PropertiesView';
 import { DocumentView } from './DocumentView';
 import './IconTagBox.scss';
 import { TagItem } from '../TagsView';
+import { returnFalse, setupMoveUpEvents } from '../../../ClientUtils';
 
 export interface IconTagProps {
     Views: DocumentView[];
@@ -93,10 +94,13 @@ export class IconTagBox extends ObservableReactComponent<IconTagProps> {
                     <button
                         key={i}
                         type="button"
-                        onClick={() => {
-                            const state = TagItem.docHasTag(this.View.Document, iconMap(i).toString()); // this.View.Document[iconMap(i).toString()];
-                            this.setIconTag(iconMap(i), !state);
-                        }}>
+                        onPointerDown={e =>
+                            setupMoveUpEvents(this, e, returnFalse, emptyFunction, clickEv => {
+                                const state = TagItem.docHasTag(this.View.Document, iconMap(i).toString()); // this.View.Document[iconMap(i).toString()];
+                                this.setIconTag(iconMap(i), !state);
+                                clickEv.stopPropagation();
+                            })
+                        }>
                         {this.getButtonIcon(this.View.Document, iconMap(i))}
                     </button>
                 </Tooltip>
-- 
cgit v1.2.3-70-g09d2

