From 3f940bd45fd1bf72f6c16edc188f754b01f689ba Mon Sep 17 00:00:00 2001
From: aidahosa1 <aisosa_idahosa@brown.edu>
Date: Fri, 21 Jun 2024 15:11:23 -0400
Subject: yay dragging

---
 .../views/collections/CollectionCardDeckView.tsx   | 231 ++++++++++++---------
 1 file changed, 138 insertions(+), 93 deletions(-)

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

diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx
index 76536ed48..2ad7f0ed1 100644
--- a/src/client/views/collections/CollectionCardDeckView.tsx
+++ b/src/client/views/collections/CollectionCardDeckView.tsx
@@ -3,7 +3,7 @@ import { observer } from 'mobx-react';
 import * as React from 'react';
 import { ClientUtils, DashColor, returnFalse, returnZero } from '../../../ClientUtils';
 import { emptyFunction, numberRange } from '../../../Utils';
-import { Doc, NumListCast } from '../../../fields/Doc';
+import { Doc, NumListCast, StrListCast } from '../../../fields/Doc';
 import { DocData } from '../../../fields/DocSymbols';
 import { Id } from '../../../fields/FieldSymbols';
 import { BoolCast, Cast, DateCast, NumCast, RTFCast, ScriptCast, StrCast } from '../../../fields/Types';
@@ -27,12 +27,14 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { SettingsManager } from '../../util/SettingsManager';
 import { Tooltip } from '@mui/material';
 import { dropActionType } from '../../util/DropActionTypes';
+import { List } from '../../../fields/List';
 
 enum cardSortings {
     Time = 'time',
     Type = 'type',
     Color = 'color',
     Custom = 'custom',
+    Drag = 'drag',
     None = '',
 }
 @observer
@@ -48,7 +50,7 @@ export class CollectionCardView extends CollectionSubView() {
     @observable _docRefs = new ObservableMap<Doc, DocumentView>();
     _draggerRef = React.createRef<HTMLDivElement>();
     @observable _maxRowCount = 10;
-    @observable _docsDraggedIndex: number[] = [];
+    @observable _docDraggedIndex: number = -1;
     @observable _isACardBeingDragged: boolean = false;
     @observable overIndex: number = -1;
 
@@ -73,12 +75,6 @@ export class CollectionCardView extends CollectionSubView() {
         }
     };
 
-    protected createDashEventsTarget = (ele: HTMLDivElement | null) => {
-        this._dropDisposer?.();
-        if (ele) {
-            this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc);
-        }
-    };
 
     constructor(props: any) {
         super(props);
@@ -145,12 +141,7 @@ export class CollectionCardView extends CollectionSubView() {
         return regularDocs;
     }
 
-    /**
-     * Determines the order in which the cards will be rendered depending on the current sort type
-     */
-    @computed get sortedDocs() {
-        return this.sort(this.childDocsWithoutLinks, this.cardSort, BoolCast(this.layoutDoc.sortDesc));
-    }
+   
 
     /**
      * Number of rows of cards to be rendered
@@ -226,27 +217,71 @@ export class CollectionCardView extends CollectionSubView() {
         return Math.abs(stepMag * (apex - index - 1)) - rowOffset;
     };
 
-    /**
-     * Translates the selected node to the middle fo the screen
-     * @param index
-     * @returns
-     */
-    // translateSelected = (index: number): number => {
-    //     // if (this.isSelected(index)) {
-    //     const middleOfPanel = this._props.PanelWidth() / 2;
-    //     const scaledNodeWidth = this.panelWidth() * 1.25;
+     findCardDropIndex = (mouseX: number, mouseY: number) => {
+
+        const amCardsTotal = this.sortedDocs.length
+        let index = 0;
+        const cardWidth = amCardsTotal < this._maxRowCount ? this._props.PanelWidth() / amCardsTotal : this._props.PanelWidth() /  this._maxRowCount;
+    
+        // Calculate the adjusted X position accounting for the initial offset
+        let adjustedX = mouseX
+
+        const amRows = Math.ceil(amCardsTotal / this._maxRowCount);
+        const rowHeight = this._props.PanelHeight( ) / amRows
+        const currRow = Math.floor((mouseY - 100) / rowHeight) //rows start at 0
+
+        if (adjustedX < 0) {
+            return 0; // Before the first column
+        }
+
+        if (amCardsTotal < this._maxRowCount)   { 
+            index = Math.floor(adjustedX / cardWidth);
+        }
+
+        else if (currRow != amRows -1 ){
+            index = Math.floor(adjustedX / cardWidth) + (currRow * this._maxRowCount)
+        }
 
-    //     // Calculate the position of the node's left edge before scaling
-    //     const nodeLeftEdge = index * this.panelWidth();
-    //     // Find the center of the node after scaling
-    //     const scaledNodeCenter = nodeLeftEdge + scaledNodeWidth / 2;
+        else {
+            // console.log(amRows + "am rows")
+            const rowAmCards = amCardsTotal - (currRow * this._maxRowCount)
+            const offset = ((this._maxRowCount - rowAmCards ) / 2) * cardWidth
+            adjustedX = mouseX - offset
 
-    //     // Calculate the translation needed to align the scaled node's center with the panel's center
-    //     const translation = middleOfPanel - scaledNodeCenter - scaledNodeWidth - scaledNodeWidth / 4;
+            index = Math.floor(adjustedX / cardWidth) + (currRow * this._maxRowCount);
+        }
+        return index;
+    };
 
-    //     return translation;
-    // };
+    @action
+    onPointerMove = (e: React.PointerEvent<HTMLDivElement>) => {
+        if (DragManager.docsBeingDragged.length != 0 ) {
+            this._isACardBeingDragged = true
+
+            const newIndex = this.findCardDropIndex(e.clientX, e.clientY);
+            
+            if (newIndex !== this._docDraggedIndex && newIndex != -1) {
+                this._docDraggedIndex = newIndex;
+                }
+        }
+    };
 
+
+    onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
+        if (de.complete.docDragData) {
+            this._isACardBeingDragged = false;
+            this._docDraggedIndex = -1;
+            e.stopPropagation()
+            const draggedDocs = de.complete.docDragData?.draggedDocuments;
+            return true;
+        }
+        return false;
+    };
+
+     @computed get sortedDocs() {
+        // console.log("hi hi hi")
+        return this.sort(this.childDocsWithoutLinks, this.cardSort, BoolCast(this.layoutDoc.sortDesc), this._docDraggedIndex);
+    }
     /**
      * Called in the sortedDocsType method. Compares the cards' value in regards to the desired sort type-- earlier cards are move to the
      * front, latter cards to the back
@@ -255,7 +290,8 @@ export class CollectionCardView extends CollectionSubView() {
      * @param isDesc
      * @returns
      */
-    sort = (docs: Doc[], sortType: cardSortings, isDesc: boolean) => {
+    sort = (docs: Doc[], sortType: cardSortings, isDesc: boolean, dragIndex: number) => {
+        // console.log('HIIIIIIIII')
         if (sortType === cardSortings.None) return docs;
         docs.sort((docA, docB) => {
             const [typeA, typeB] = (() => {
@@ -281,9 +317,25 @@ export class CollectionCardView extends CollectionSubView() {
             return isDesc ? -out : out; // Reverse the sort order if descending is true
         });
 
+        if (dragIndex != -1){
+            // console.log("what what")
+
+            const draggedDoc = DragManager.docsBeingDragged[0]
+            const originalIndex = docs.findIndex(doc => doc === draggedDoc);
+
+                    
+            // Remove the dragged document from its original position
+            docs.splice(originalIndex, 1);
+            // Insert the dragged document at the new position
+            docs.splice(dragIndex, 0, draggedDoc);
+                // }
+        }
+
         return docs;
     };
 
+
+
     displayDoc = (doc: Doc, screenToLocalTransform: () => Transform) => (
         <DocumentView
             // eslint-disable-next-line react/jsx-props-no-spreading
@@ -361,16 +413,7 @@ export class CollectionCardView extends CollectionSubView() {
         return trans + this.translateY(amCards, calcRowIndex, realIndex);
     };
 
-    /**
-     * Toggles the buttons between on and off when creating custom sort groupings/changing those created by gpt
-     * @param childPairIndex
-     * @param buttonID
-     * @param doc
-     */
-    toggleButton = undoable((buttonID: number, doc: Doc) => {
-        this.cardSort_customField && (doc[this.cardSort_customField] = buttonID);
-    }, 'toggle custom button');
-
+  
     /**
      * A list of the text content of all the child docs. RTF documents will have just their text and pdf documents will have the first 50 words.
      * Image documents are converted to bse64 and gpt generates a description for them. all other documents use their title. This string is
@@ -456,27 +499,37 @@ export class CollectionCardView extends CollectionSubView() {
      * @returns
      */
     renderButtons = (doc: Doc, cardSort: cardSortings): JSX.Element | null => {
-        if (cardSort !== cardSortings.Custom) return null;
+        // if (cardSort !== cardSortings.Custom) return null;
 
-        const amButtons = Math.max(
-            4,
-            this.childDocs?.reduce((set, d) => {
-                if (this.cardSort_customField) {
-                    set.add(NumCast(d[this.cardSort_customField]));
-                }
-                return set;
-            }, new Set<number>()).size ?? 0
-        );
+        const amButtons = 4
+
+        // const amButtons = Math.max(
+        //     4,
+        //     this.childDocs?.reduce((set, d) => {
+        //         if (this.cardSort_customField) {
+        //             set.add(NumCast(d[this.cardSort_customField]));
+        //         }
+        //         return set;
+        //     }, new Set<number>()).size ?? 0
+        // );
 
         const activeButtonIndex = CollectionCardView.getButtonGroup(this.cardSort_customField, doc);
+
         const totalWidth = amButtons * 72 + amButtons * 2 * 5 + 6;
 
+        const iconMap: { [key: number]: any } = {
+            0: 'star',
+            1: 'heart',
+            2: 'cloud',
+            3: 'bolt'
+        };
+
         return (
             <div className="card-button-container" style={{ width: `${totalWidth}px`, fontSize: '50px' }}>
                 {numberRange(amButtons).map(i => (
-                    <Tooltip key={i} title={<div className="dash-tooltip">Click to add/remove this card from group {i + 1}</div>}>
-                        <button type="button" onClick={() => this.toggleButton(i, doc)}>
-                            {this.getButtonIcon(activeButtonIndex === i)}
+                    <Tooltip key={i} title={<div className="dash-tooltip">Click to add/remove this card from the {iconMap[i]} group</div>}>
+                        <button type="button" onClick={() => this.toggleButton(doc, iconMap[i] )}>
+                            {this.getButtonIcon(doc, iconMap[i])}
                         </button>
                     </Tooltip>
                 ))}
@@ -484,53 +537,44 @@ export class CollectionCardView extends CollectionSubView() {
         );
     };
 
-    getButtonIcon = (isActive: boolean): JSX.Element => {
-        const iconMap: { [key: string]: any } = {
-            like: 'heart',
-            chat: 'robot',
-            idea: 'cloud',
-        };
+      /**
+     * Toggles the buttons between on and off when creating custom sort groupings/changing those created by gpt
+     * @param childPairIndex
+     * @param buttonID
+     * @param doc
+     */
+      toggleButton = undoable((doc: Doc, icon: string) => {
+
+
+
+        // this.cardSort_customField && (doc[this.cardSort_customField] = buttonID);
+
+        // doc.cardSort_activeIcons = new List<string>()
+
 
-        const icon = iconMap[this.cardSort_customField ?? ''] || 'star';
+        const list = StrListCast(doc.cardSort_activeIcons);
+        doc.cardSort_activeIcons = new List<string>(list.includes(icon) ? list.filter(d => d !== icon) : [...list, icon]);
+
+
+
+        // StrListCast(doc.cardSort_activeIcons).push(iconMap[buttonID])
+    }, 'toggle card tag');
+
+
+    getButtonIcon = (doc: Doc, icon: any): JSX.Element => {
+
+        const isActive = StrListCast(doc.cardSort_activeIcons).includes(icon)
+
+        console.log(StrListCast(doc.cardSort_activeIcons))
         const color = isActive ? '#4476f7' : '#323232';
 
         return <FontAwesomeIcon icon={icon} size="lg" style={{ color }} />;
     };
 
-    // @action
-    // onDragStart = (index: number) => {
-    //     this.draggedIndex = index;
-    // };
-
-    // @action
-    // onDragOver = (index: number) => {
-    //     if (this.draggedIndex !== index) {
-    //         this.overIndex = index;
-    //     }
-    // };
-
-    // @action
-    // onDrop = () => {
-    //     if (this.draggedIndex !== -1 && this.overIndex !== -1) {
-    //         const draggedDoc = this.sortedDocs[this.draggedIndex];
-    //         this.sortedDocs.splice(this.draggedIndex, 1);
-    //         this.sortedDocs.splice(this.overIndex, 0, draggedDoc);
-    //         this.draggedIndex = -1;
-    //         this.overIndex = -1;
-    //     }
-    // };
-
-    // @action
-    // onDragEnd = () => {
-    //     this.draggedIndex = -1;
-    //     this.overIndex = -1;
-    // };
-
     /**
      * Actually renders all the cards
      */
     renderCards = () => {
-        console.log(DragManager.docsBeingDragged.length + 'drag ha');
         const anySelected = this.childDocs.some(doc => DocumentView.SelectedDocs().includes(doc));
         const isEmpty = this.childDocsWithoutLinks.length === 0;
 
@@ -599,8 +643,9 @@ export class CollectionCardView extends CollectionSubView() {
     render() {
         return (
             <div
+                onPointerMove={e => this.onPointerMove(e)}
                 className="collectionCardView-outer"
-                ref={this.createDashEventsTarget}
+                ref={(ele: HTMLDivElement | null) => this.createDashEventsTarget(ele)}
                 style={{
                     background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor),
                     color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color),
-- 
cgit v1.2.3-70-g09d2

